IgH EtherCAT Master  1.5.2
master.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * $Id$
4  *
5  * Copyright (C) 2006-2012 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  * vim: expandtab
29  *
30  *****************************************************************************/
31 
37 /*****************************************************************************/
38 
39 #include <linux/module.h>
40 #include <linux/kernel.h>
41 #include <linux/string.h>
42 #include <linux/slab.h>
43 #include <linux/delay.h>
44 #include <linux/device.h>
45 #include <linux/version.h>
46 #include <linux/hrtimer.h>
47 #include <linux/vmalloc.h>
48 
49 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
50 #include <linux/sched/types.h> // struct sched_param
51 #include <linux/sched/signal.h> // signal_pending
52 #endif
53 
54 #include "globals.h"
55 #include "slave.h"
56 #include "slave_config.h"
57 #include "device.h"
58 #include "datagram.h"
59 #include "mailbox.h"
60 #ifdef EC_EOE
61 #include "ethernet.h"
62 #endif
63 #include "master.h"
64 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0)
65 #include <linux/sched/signal.h>
66 #include <uapi/linux/sched/types.h>
67 #endif
68 
69 /*****************************************************************************/
70 
73 #define DEBUG_INJECT 0
74 
77 #define FORCE_OUTPUT_CORRUPTED 0
78 
79 #ifdef EC_HAVE_CYCLES
80 
83 static cycles_t timeout_cycles;
84 
87 static cycles_t ext_injection_timeout_cycles;
88 
89 #else
90 
93 static unsigned long timeout_jiffies;
94 
97 static unsigned long ext_injection_timeout_jiffies;
98 
99 #endif
100 
103 const unsigned int rate_intervals[] = {
104  1, 10, 60
105 };
106 
107 /*****************************************************************************/
108 
111 static int ec_master_idle_thread(void *);
112 static int ec_master_operation_thread(void *);
113 #ifdef EC_EOE
114 static int ec_master_eoe_thread(void *);
115 #endif
119 
120 /*****************************************************************************/
121 
125 {
126 #ifdef EC_HAVE_CYCLES
127  timeout_cycles = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
128  ext_injection_timeout_cycles =
129  (cycles_t) EC_SDO_INJECTION_TIMEOUT /* us */ * (cpu_khz / 1000);
130 #else
131  // one jiffy may always elapse between time measurement
132  timeout_jiffies = max(EC_IO_TIMEOUT * HZ / 1000000, 1);
134  max(EC_SDO_INJECTION_TIMEOUT * HZ / 1000000, 1);
135 #endif
136 }
137 
138 /*****************************************************************************/
139 
146  unsigned int index,
147  const uint8_t *main_mac,
148  const uint8_t *backup_mac,
149  dev_t device_number,
150  struct class *class,
151  unsigned int debug_level
152  )
153 {
154  int ret;
155  unsigned int dev_idx, i;
156 
157  master->index = index;
158  master->reserved = 0;
159 
160  ec_lock_init(&master->master_sem);
161 
162  for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_MAX_NUM_DEVICES; dev_idx++) {
163  master->macs[dev_idx] = NULL;
164  }
165 
166  master->macs[EC_DEVICE_MAIN] = main_mac;
167 
168 #if EC_MAX_NUM_DEVICES > 1
169  master->macs[EC_DEVICE_BACKUP] = backup_mac;
170  master->num_devices = 1 + !ec_mac_is_zero(backup_mac);
171 #else
172  if (!ec_mac_is_zero(backup_mac)) {
173  EC_MASTER_WARN(master, "Ignoring backup MAC address!");
174  }
175 #endif
176 
178 
179  ec_lock_init(&master->device_sem);
180 
181  master->phase = EC_ORPHANED;
182  master->active = 0;
183  master->config_changed = 0;
184  master->injection_seq_fsm = 0;
185  master->injection_seq_rt = 0;
186  master->reboot = 0;
187 
188  master->slaves = NULL;
189  master->slave_count = 0;
190 
191  INIT_LIST_HEAD(&master->configs);
192  INIT_LIST_HEAD(&master->domains);
193  INIT_LIST_HEAD(&master->sii_images);
194 
195  master->app_time = 0ULL;
196  master->dc_ref_time = 0ULL;
197  master->dc_offset_valid = 0;
198 
199  master->scan_busy = 0;
200  master->allow_scan = 1;
201  ec_lock_init(&master->scan_sem);
202  init_waitqueue_head(&master->scan_queue);
203 
204  master->config_busy = 0;
205  ec_lock_init(&master->config_sem);
206  init_waitqueue_head(&master->config_queue);
207 
208  INIT_LIST_HEAD(&master->datagram_queue);
209  master->datagram_index = 0;
210 
211  INIT_LIST_HEAD(&master->ext_datagram_queue);
212  ec_lock_init(&master->ext_queue_sem);
213 
214  master->ext_ring_idx_rt = 0;
215  master->ext_ring_idx_fsm = 0;
216  master->rt_slave_requests = 0;
217  master->rt_slaves_available = 0;
218 
219  // init external datagram ring
220  for (i = 0; i < EC_EXT_RING_SIZE; i++) {
221  ec_datagram_t *datagram = &master->ext_datagram_ring[i];
222  ec_datagram_init(datagram);
223  snprintf(datagram->name, EC_DATAGRAM_NAME_SIZE, "ext-%u", i);
224  }
225 
226  // send interval in IDLE phase
227  ec_master_set_send_interval(master, 1000000 / HZ);
228 
229  master->fsm_slave = NULL;
230  INIT_LIST_HEAD(&master->fsm_exec_list);
231  master->fsm_exec_count = 0U;
232 
233  master->debug_level = debug_level;
234  master->stats.timeouts = 0;
235  master->stats.corrupted = 0;
236  master->stats.unmatched = 0;
237  master->stats.output_jiffies = 0;
238 
239  // set up pcap debugging
240  if (pcap_size > 0) {
241  master->pcap_data = vmalloc(pcap_size);
242  } else {
243  master->pcap_data = NULL;
244  }
245  master->pcap_curr_data = master->pcap_data;
246 
247  master->thread = NULL;
248 
249 #ifdef EC_EOE
250  master->eoe_thread = NULL;
251  INIT_LIST_HEAD(&master->eoe_handlers);
252 #endif
253 
254  ec_lock_init(&master->io_sem);
255  master->send_cb = NULL;
256  master->receive_cb = NULL;
257  master->cb_data = NULL;
258  master->app_send_cb = NULL;
259  master->app_receive_cb = NULL;
260  master->app_cb_data = NULL;
261 
262  INIT_LIST_HEAD(&master->sii_requests);
263  INIT_LIST_HEAD(&master->emerg_reg_requests);
264 
265  init_waitqueue_head(&master->request_queue);
266 
267  // init devices
268  for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
269  dev_idx++) {
270  ret = ec_device_init(&master->devices[dev_idx], master);
271  if (ret < 0) {
272  goto out_clear_devices;
273  }
274  }
275 
276  // init state machine datagram
277  ec_datagram_init(&master->fsm_datagram);
278  snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm");
280  if (ret < 0) {
282  EC_MASTER_ERR(master, "Failed to allocate FSM datagram.\n");
283  goto out_clear_devices;
284  }
285 
286  // create state machine object
287  ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram);
288 
289  // alloc external datagram ring
290  for (i = 0; i < EC_EXT_RING_SIZE; i++) {
291  ec_datagram_t *datagram = &master->ext_datagram_ring[i];
292  ret = ec_datagram_prealloc(datagram, EC_MAX_DATA_SIZE);
293  if (ret) {
294  EC_MASTER_ERR(master, "Failed to allocate external"
295  " datagram %u.\n", i);
296  goto out_clear_ext_datagrams;
297  }
298  }
299 
300  // init reference sync datagram
302  snprintf(master->ref_sync_datagram.name, EC_DATAGRAM_NAME_SIZE,
303  "refsync");
304  ret = ec_datagram_prealloc(&master->ref_sync_datagram, 4);
305  if (ret < 0) {
307  EC_MASTER_ERR(master, "Failed to allocate reference"
308  " synchronisation datagram.\n");
309  goto out_clear_ext_datagrams;
310  }
311 
312  // init sync datagram
314  snprintf(master->sync_datagram.name, EC_DATAGRAM_NAME_SIZE, "sync");
315  ret = ec_datagram_prealloc(&master->sync_datagram, 4);
316  if (ret < 0) {
318  EC_MASTER_ERR(master, "Failed to allocate"
319  " synchronisation datagram.\n");
320  goto out_clear_ref_sync;
321  }
322 
323  // init sync64 datagram
325  snprintf(master->sync64_datagram.name, EC_DATAGRAM_NAME_SIZE, "sync64");
326  ret = ec_datagram_prealloc(&master->sync64_datagram, 8);
327  if (ret < 0) {
329  EC_MASTER_ERR(master, "Failed to allocate 64bit ref slave"
330  " system clock datagram.\n");
331  goto out_clear_sync;
332  }
333 
334  // init sync monitor datagram
336  snprintf(master->sync_mon_datagram.name, EC_DATAGRAM_NAME_SIZE,
337  "syncmon");
338  ret = ec_datagram_brd(&master->sync_mon_datagram, 0x092c, 4);
339  if (ret < 0) {
341  EC_MASTER_ERR(master, "Failed to allocate sync"
342  " monitoring datagram.\n");
343  goto out_clear_sync64;
344  }
345 
346  master->dc_ref_config = NULL;
347  master->dc_ref_clock = NULL;
348 
349  // init character device
350  ret = ec_cdev_init(&master->cdev, master, device_number);
351  if (ret)
352  goto out_clear_sync_mon;
353 
354 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
355  master->class_device = device_create(class, NULL,
356  MKDEV(MAJOR(device_number), master->index), NULL,
357  "EtherCAT%u", master->index);
358 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
359  master->class_device = device_create(class, NULL,
360  MKDEV(MAJOR(device_number), master->index),
361  "EtherCAT%u", master->index);
362 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 15)
363  master->class_device = class_device_create(class, NULL,
364  MKDEV(MAJOR(device_number), master->index), NULL,
365  "EtherCAT%u", master->index);
366 #else
367  master->class_device = class_device_create(class,
368  MKDEV(MAJOR(device_number), master->index), NULL,
369  "EtherCAT%u", master->index);
370 #endif
371  if (IS_ERR(master->class_device)) {
372  EC_MASTER_ERR(master, "Failed to create class device!\n");
373  ret = PTR_ERR(master->class_device);
374  goto out_clear_cdev;
375  }
376 
377 #ifdef EC_RTDM
378  // init RTDM device
379  ret = ec_rtdm_dev_init(&master->rtdm_dev, master);
380  if (ret) {
381  goto out_unregister_class_device;
382  }
383 #endif
384 
385  return 0;
386 
387 #ifdef EC_RTDM
388 out_unregister_class_device:
389 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
390  device_unregister(master->class_device);
391 #else
392  class_device_unregister(master->class_device);
393 #endif
394 #endif
395 out_clear_cdev:
396  ec_cdev_clear(&master->cdev);
397 out_clear_sync_mon:
399 out_clear_sync64:
401 out_clear_sync:
403 out_clear_ref_sync:
405 out_clear_ext_datagrams:
406  for (i = 0; i < EC_EXT_RING_SIZE; i++) {
408  }
409  ec_fsm_master_clear(&master->fsm);
411 out_clear_devices:
412  for (; dev_idx > 0; dev_idx--) {
413  ec_device_clear(&master->devices[dev_idx - 1]);
414  }
415  return ret;
416 }
417 
418 /*****************************************************************************/
419 
423  ec_master_t *master
424  )
425 {
426  unsigned int dev_idx, i;
427 
428 #ifdef EC_RTDM
429  ec_rtdm_dev_clear(&master->rtdm_dev);
430 #endif
431 
432 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
433  device_unregister(master->class_device);
434 #else
435  class_device_unregister(master->class_device);
436 #endif
437 
438  ec_cdev_clear(&master->cdev);
439 
441 #ifdef EC_EOE
442  // free all EoE handlers
443  ec_master_clear_eoe_handlers(master, 1);
444 #endif
445  ec_master_clear_domains(master);
447  ec_master_clear_slaves(master);
449 
454 
455  for (i = 0; i < EC_EXT_RING_SIZE; i++) {
457  }
458 
459  ec_fsm_master_clear(&master->fsm);
461 
462  for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
463  dev_idx++) {
464  ec_device_clear(&master->devices[dev_idx]);
465  }
466 
467  if (master->pcap_data) {
468  vfree(master->pcap_data);
469  master->pcap_data = NULL;
470  master->pcap_curr_data = NULL;
471  }
472 }
473 
474 /*****************************************************************************/
475 
476 #ifdef EC_EOE
477 
481  ec_master_t *master,
482  unsigned int free_all
483  )
484 {
485  ec_eoe_t *eoe, *next;
486 
487  list_for_each_entry_safe(eoe, next, &master->eoe_handlers, list) {
488  if (free_all || eoe->auto_created) {
489  // free_all or auto created eoe: clear and free
490  list_del(&eoe->list);
491  ec_eoe_clear(eoe);
492  kfree(eoe);
493  } else {
494  // manaully created eoe: clear slave ref
495  ec_eoe_clear_slave(eoe);
496  }
497  }
498 }
499 #endif
500 
501 /*****************************************************************************/
502 
506 {
507  ec_slave_config_t *sc, *next;
508 
509  master->dc_ref_config = NULL;
510 
511  list_for_each_entry_safe(sc, next, &master->configs, list) {
512  list_del(&sc->list);
514  kfree(sc);
515  }
516 }
517 
518 /*****************************************************************************/
519 
523 {
524  unsigned int i;
525  ec_pdo_t *pdo, *next_pdo;
526 
527  // free all sync managers
528  if (sii_image->sii.syncs) {
529  for (i = 0; i < sii_image->sii.sync_count; i++) {
530  ec_sync_clear(&sii_image->sii.syncs[i]);
531  }
532  kfree(sii_image->sii.syncs);
533  sii_image->sii.syncs = NULL;
534  }
535 
536  // free all strings
537  if (sii_image->sii.strings) {
538  for (i = 0; i < sii_image->sii.string_count; i++)
539  kfree(sii_image->sii.strings[i]);
540  kfree(sii_image->sii.strings);
541  }
542 
543  // free all SII PDOs
544  list_for_each_entry_safe(pdo, next_pdo, &sii_image->sii.pdos, list) {
545  list_del(&pdo->list);
546  ec_pdo_clear(pdo);
547  kfree(pdo);
548  }
549 
550  if (sii_image->words) {
551  kfree(sii_image->words);
552  }
553 }
554 
555 /*****************************************************************************/
556 
560  ec_master_t *master
561  )
562 {
563  ec_sii_image_t *sii_image, *next;
564 
565  list_for_each_entry_safe(sii_image, next, &master->sii_images, list) {
566 #ifdef EC_SII_CACHE
567  if ((master->phase != EC_OPERATION) ||
568  ((sii_image->sii.serial_number == 0) && (sii_image->sii.alias == 0)))
569 #endif
570  {
571  list_del(&sii_image->list);
572  ec_sii_image_clear(sii_image);
573  kfree(sii_image);
574  }
575  }
576 }
577 
578 /*****************************************************************************/
579 
586 {
587  master->rt_slaves_available = 0;
588 }
589 
590 /*****************************************************************************/
591 
598 {
599  master->rt_slaves_available = 1;
600 }
601 
602 /*****************************************************************************/
603 
607 {
608  ec_slave_t *slave;
609 
610  master->dc_ref_clock = NULL;
611 
612  // External requests are obsolete, so we wake pending waiters and remove
613  // them from the list.
614 
615  while (!list_empty(&master->sii_requests)) {
616  ec_sii_write_request_t *request =
617  list_entry(master->sii_requests.next,
618  ec_sii_write_request_t, list);
619  list_del_init(&request->list); // dequeue
620  EC_MASTER_WARN(master, "Discarding SII request, slave %s-%u about"
621  " to be deleted.\n", ec_device_names[request->slave->device_index!=0],
622  request->slave->ring_position);
623  request->state = EC_INT_REQUEST_FAILURE;
624  wake_up_all(&master->request_queue);
625  }
626 
627  master->fsm_slave = NULL;
628  INIT_LIST_HEAD(&master->fsm_exec_list);
629  master->fsm_exec_count = 0;
630 
631  for (slave = master->slaves;
632  slave < master->slaves + master->slave_count;
633  slave++) {
634  ec_slave_clear(slave);
635  }
636 
637  if (master->slaves) {
638  kfree(master->slaves);
639  master->slaves = NULL;
640  }
641 
642  master->slave_count = 0;
643 }
644 
645 /*****************************************************************************/
646 
650 {
651  ec_domain_t *domain, *next;
652 
653  list_for_each_entry_safe(domain, next, &master->domains, list) {
654  list_del(&domain->list);
655  ec_domain_clear(domain);
656  kfree(domain);
657  }
658 }
659 
660 /*****************************************************************************/
661 
665  ec_master_t *master
666  )
667 {
668  ec_lock_down(&master->master_sem);
669  ec_master_clear_domains(master);
671  ec_lock_up(&master->master_sem);
672 }
673 
674 /*****************************************************************************/
675 
679  void *cb_data
680  )
681 {
682  ec_master_t *master = (ec_master_t *) cb_data;
683  ec_lock_down(&master->io_sem);
684  ecrt_master_send_ext(master);
685  ec_lock_up(&master->io_sem);
686 }
687 
688 /*****************************************************************************/
689 
693  void *cb_data
694  )
695 {
696  ec_master_t *master = (ec_master_t *) cb_data;
697  ec_lock_down(&master->io_sem);
698  ecrt_master_receive(master);
699  ec_lock_up(&master->io_sem);
700 }
701 
702 /*****************************************************************************/
703 
710  ec_master_t *master,
711  int (*thread_func)(void *),
712  const char *name
713  )
714 {
715  EC_MASTER_INFO(master, "Starting %s thread.\n", name);
716  master->thread = kthread_run(thread_func, master, name);
717  if (IS_ERR(master->thread)) {
718  int err = (int) PTR_ERR(master->thread);
719  EC_MASTER_ERR(master, "Failed to start master thread (error %i)!\n",
720  err);
721  master->thread = NULL;
722  return err;
723  }
724 
725  return 0;
726 }
727 
728 /*****************************************************************************/
729 
733  ec_master_t *master
734  )
735 {
736  unsigned long sleep_jiffies;
737 
738  if (!master->thread) {
739  EC_MASTER_WARN(master, "%s(): Already finished!\n", __func__);
740  return;
741  }
742 
743  EC_MASTER_DBG(master, 1, "Stopping master thread.\n");
744 
745  kthread_stop(master->thread);
746  master->thread = NULL;
747  EC_MASTER_INFO(master, "Master thread exited.\n");
748 
749  if (master->fsm_datagram.state != EC_DATAGRAM_SENT) {
750  return;
751  }
752 
753  // wait for FSM datagram
754  sleep_jiffies = max(HZ / 100, 1); // 10 ms, at least 1 jiffy
755  schedule_timeout(sleep_jiffies);
756 }
757 
758 /*****************************************************************************/
759 
765  ec_master_t *master
766  )
767 {
768  int ret;
769  ec_device_index_t dev_idx;
770 #ifdef EC_EOE
771  int i;
772  int master_index = 0;
773  uint16_t alias, ring_position = 0;
774 #endif
775 
776  EC_MASTER_DBG(master, 1, "ORPHANED -> IDLE.\n");
777 
780  master->cb_data = master;
781 
782  master->phase = EC_IDLE;
783 
784  // reset number of responding slaves to trigger scanning
785  for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
786  dev_idx++) {
787  master->fsm.slaves_responding[dev_idx] = 0;
788  }
789 
790 #ifdef EC_EOE
791  // create eoe interfaces for this master on startup
792  // Note: needs the masters main device to be configured to init the
793  // eoe's mac address
794  for (i = 0; i < eoe_count; i++) {
795  ret = ec_eoe_parse(eoe_interfaces[i], &master_index, &alias,
796  &ring_position);
797 
798  if ((ret == 0) && (master_index == master->index)) {
799  EC_MASTER_INFO(master, "Adding EOE iface \"%s\" for master %d, "
800  "alias %u, ring position %u.\n",
801  eoe_interfaces[i], master_index, alias, ring_position);
802  ecrt_master_eoe_addif(master, alias, ring_position);
803  }
804  }
805 #endif
806 
808  "EtherCAT-IDLE");
809  if (ret)
810  master->phase = EC_ORPHANED;
811 
812  return ret;
813 }
814 
815 /*****************************************************************************/
816 
820 {
821  EC_MASTER_DBG(master, 1, "IDLE -> ORPHANED.\n");
822 
823  master->phase = EC_ORPHANED;
824 
826 #ifdef EC_EOE
827  ec_master_eoe_stop(master);
828 #endif
829  ec_master_thread_stop(master);
830 
831  ec_lock_down(&master->master_sem);
832  ec_master_clear_slaves(master);
834  ec_lock_up(&master->master_sem);
835 
836  ec_fsm_master_reset(&master->fsm);
837 }
838 
839 /*****************************************************************************/
840 
846  ec_master_t *master
847  )
848 {
849  int ret = 0;
850  ec_slave_t *slave;
851 
852  EC_MASTER_DBG(master, 1, "IDLE -> OPERATION.\n");
853 
854  ec_lock_down(&master->config_sem);
855  if (master->config_busy) {
856  ec_lock_up(&master->config_sem);
857 
858  // wait for slave configuration to complete
859  ret = wait_event_interruptible(master->config_queue,
860  !master->config_busy);
861  if (ret) {
862  EC_MASTER_INFO(master, "Finishing slave configuration"
863  " interrupted by signal.\n");
864  goto out_return;
865  }
866 
867  EC_MASTER_DBG(master, 1, "Waiting for pending slave"
868  " configuration returned.\n");
869  } else {
870  ec_lock_up(&master->config_sem);
871  }
872 
873  ec_lock_down(&master->scan_sem);
874  master->allow_scan = 0; // 'lock' the slave list
875  if (!master->scan_busy) {
876  ec_lock_up(&master->scan_sem);
877  } else {
878  ec_lock_up(&master->scan_sem);
879 
880  // wait for slave scan to complete
881  ret = wait_event_interruptible(master->scan_queue,
882  !master->scan_busy);
883  if (ret) {
884  EC_MASTER_INFO(master, "Waiting for slave scan"
885  " interrupted by signal.\n");
886  goto out_allow;
887  }
888 
889  EC_MASTER_DBG(master, 1, "Waiting for pending"
890  " slave scan returned.\n");
891  }
892 
893  // set states for all slaves
894  for (slave = master->slaves;
895  slave < master->slaves + master->slave_count;
896  slave++) {
898  }
899 
900  master->phase = EC_OPERATION;
901  master->app_send_cb = NULL;
902  master->app_receive_cb = NULL;
903  master->app_cb_data = NULL;
904  return ret;
905 
906 out_allow:
907  master->allow_scan = 1;
908 out_return:
909  return ret;
910 }
911 
912 /*****************************************************************************/
913 
917  ec_master_t *master
918  )
919 {
920  if (master->active) {
921  ecrt_master_deactivate(master); // also clears config
922  } else {
923  ec_master_clear_config(master);
924  }
925 
926  /* Re-allow scanning for IDLE phase. */
927  master->allow_scan = 1;
928 
929  EC_MASTER_DBG(master, 1, "OPERATION -> IDLE.\n");
930 
931  master->phase = EC_IDLE;
932 }
933 
934 /*****************************************************************************/
935 
939  ec_master_t *master
940  )
941 {
942  ec_datagram_t *datagram;
943  size_t queue_size = 0, new_queue_size = 0;
944 #if DEBUG_INJECT
945  unsigned int datagram_count = 0;
946 #endif
947 
948  if (master->ext_ring_idx_rt == master->ext_ring_idx_fsm) {
949  // nothing to inject
950  return;
951  }
952 
953  list_for_each_entry(datagram, &master->datagram_queue, queue) {
954  if (datagram->state == EC_DATAGRAM_QUEUED) {
955  queue_size += datagram->data_size;
956  }
957  }
958 
959 #if DEBUG_INJECT
960  EC_MASTER_DBG(master, 1, "Injecting datagrams, queue_size=%zu\n",
961  queue_size);
962 #endif
963 
964  while (master->ext_ring_idx_rt != master->ext_ring_idx_fsm) {
965  datagram = &master->ext_datagram_ring[master->ext_ring_idx_rt];
966 
967  if (datagram->state != EC_DATAGRAM_INIT) {
968  // skip datagram
969  master->ext_ring_idx_rt =
970  (master->ext_ring_idx_rt + 1) % EC_EXT_RING_SIZE;
971  continue;
972  }
973 
974  new_queue_size = queue_size + datagram->data_size;
975  if (new_queue_size <= master->max_queue_size) {
976 #if DEBUG_INJECT
977  EC_MASTER_DBG(master, 1, "Injecting datagram %s"
978  " size=%zu, queue_size=%zu\n", datagram->name,
979  datagram->data_size, new_queue_size);
980  datagram_count++;
981 #endif
982 #ifdef EC_HAVE_CYCLES
983  datagram->cycles_sent = 0;
984 #endif
985  datagram->jiffies_sent = 0;
986  ec_master_queue_datagram(master, datagram);
987  queue_size = new_queue_size;
988  }
989  else if (datagram->data_size > master->max_queue_size) {
990  datagram->state = EC_DATAGRAM_ERROR;
991  EC_MASTER_ERR(master, "External datagram %s is too large,"
992  " size=%zu, max_queue_size=%zu\n",
993  datagram->name, datagram->data_size,
994  master->max_queue_size);
995  }
996  else { // datagram does not fit in the current cycle
997 #ifdef EC_HAVE_CYCLES
998  cycles_t cycles_now = get_cycles();
999 
1000  if (cycles_now - datagram->cycles_sent
1001  > ext_injection_timeout_cycles)
1002 #else
1003  if (jiffies - datagram->jiffies_sent
1005 #endif
1006  {
1007 #if defined EC_RT_SYSLOG || DEBUG_INJECT
1008  unsigned int time_us;
1009 #endif
1010 
1011  datagram->state = EC_DATAGRAM_ERROR;
1012 
1013 #if defined EC_RT_SYSLOG || DEBUG_INJECT
1014 #ifdef EC_HAVE_CYCLES
1015  time_us = (unsigned int)
1016  ((cycles_now - datagram->cycles_sent) * 1000LL)
1017  / cpu_khz;
1018 #else
1019  time_us = (unsigned int)
1020  ((jiffies - datagram->jiffies_sent) * 1000000 / HZ);
1021 #endif
1022  EC_MASTER_ERR(master, "Timeout %u us: Injecting"
1023  " external datagram %s size=%zu,"
1024  " max_queue_size=%zu\n", time_us, datagram->name,
1025  datagram->data_size, master->max_queue_size);
1026 #endif
1027  }
1028  else {
1029 #if DEBUG_INJECT
1030  EC_MASTER_DBG(master, 1, "Deferred injecting"
1031  " external datagram %s size=%u, queue_size=%u\n",
1032  datagram->name, datagram->data_size, queue_size);
1033 #endif
1034  break;
1035  }
1036  }
1037 
1038  master->ext_ring_idx_rt =
1039  (master->ext_ring_idx_rt + 1) % EC_EXT_RING_SIZE;
1040  }
1041 
1042 #if DEBUG_INJECT
1043  EC_MASTER_DBG(master, 1, "Injected %u datagrams.\n", datagram_count);
1044 #endif
1045 }
1046 
1047 /*****************************************************************************/
1048 
1053  ec_master_t *master,
1054  unsigned int send_interval
1055  )
1056 {
1057  master->send_interval = send_interval;
1058  master->max_queue_size =
1059  (send_interval * 1000) / EC_BYTE_TRANSMISSION_TIME_NS;
1060  master->max_queue_size -= master->max_queue_size / 10;
1061 }
1062 
1063 /*****************************************************************************/
1064 
1068  ec_master_t *master
1069  )
1070 {
1071  master->reboot = 1;
1072 }
1073 
1074 /*****************************************************************************/
1075 
1081  ec_master_t *master
1082  )
1083 {
1084  if ((master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE !=
1085  master->ext_ring_idx_rt) {
1086  ec_datagram_t *datagram =
1087  &master->ext_datagram_ring[master->ext_ring_idx_fsm];
1088  /* Record the queued time for ec_master_inject_external_datagrams */
1089 #ifdef EC_HAVE_CYCLES
1090  datagram->cycles_sent = get_cycles();
1091 #endif
1092  datagram->jiffies_sent = jiffies;
1093 
1094  return datagram;
1095  }
1096  else {
1097  return NULL;
1098  }
1099 }
1100 
1101 /*****************************************************************************/
1102 
1106  ec_master_t *master,
1107  ec_datagram_t *datagram
1108  )
1109 {
1110  ec_datagram_t *queued_datagram;
1111 
1112  /* It is possible, that a datagram in the queue is re-initialized with the
1113  * ec_datagram_<type>() methods and then shall be queued with this method.
1114  * In that case, the state is already reset to EC_DATAGRAM_INIT. Check if
1115  * the datagram is queued to avoid duplicate queuing (which results in an
1116  * infinite loop!). Set the state to EC_DATAGRAM_QUEUED again, probably
1117  * causing an unmatched datagram. */
1118  list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
1119  if (queued_datagram == datagram) {
1120  datagram->skip_count++;
1121 #ifdef EC_RT_SYSLOG
1122  EC_MASTER_DBG(master, 1,
1123  "Datagram %p already queued (skipping).\n", datagram);
1124 #endif
1125  datagram->state = EC_DATAGRAM_QUEUED;
1126  return;
1127  }
1128  }
1129 
1130  if (datagram->state != EC_DATAGRAM_INVALID) {
1131  list_add_tail(&datagram->queue, &master->datagram_queue);
1132  datagram->state = EC_DATAGRAM_QUEUED;
1133  }
1134 }
1135 
1136 /*****************************************************************************/
1137 
1141  ec_master_t *master,
1142  ec_datagram_t *datagram
1143  )
1144 {
1145  ec_lock_down(&master->ext_queue_sem);
1146  list_add_tail(&datagram->queue, &master->ext_datagram_queue);
1147  ec_lock_up(&master->ext_queue_sem);
1148 }
1149 
1150 /*****************************************************************************/
1151 
1152 static int index_in_use(ec_master_t *master, uint8_t index)
1153 {
1154  ec_datagram_t *datagram;
1155  list_for_each_entry(datagram, &master->datagram_queue, queue)
1156  if (datagram->state == EC_DATAGRAM_SENT && datagram->index == index)
1157  return 1;
1158  return 0;
1159 }
1160 
1165  ec_master_t *master,
1166  ec_device_index_t device_index
1167  )
1168 {
1169  ec_datagram_t *datagram, *next;
1170  size_t datagram_size;
1171  uint8_t *frame_data, *cur_data = NULL;
1172  void *follows_word;
1173 #ifdef EC_HAVE_CYCLES
1174  cycles_t cycles_start, cycles_sent, cycles_end;
1175 #endif
1176  unsigned long jiffies_sent;
1177  unsigned int frame_count, more_datagrams_waiting;
1178  struct list_head sent_datagrams;
1179  size_t sent_bytes = 0;
1180  uint8_t last_index;
1181 
1182 #ifdef EC_HAVE_CYCLES
1183  cycles_start = get_cycles();
1184 #endif
1185  frame_count = 0;
1186  INIT_LIST_HEAD(&sent_datagrams);
1187 
1188  EC_MASTER_DBG(master, 2, "%s(device_index = %u)\n",
1189  __func__, device_index);
1190 
1191  do {
1192  frame_data = NULL;
1193  follows_word = NULL;
1194  more_datagrams_waiting = 0;
1195 
1196  // fill current frame with datagrams
1197  list_for_each_entry(datagram, &master->datagram_queue, queue) {
1198  if (datagram->state != EC_DATAGRAM_QUEUED ||
1199  datagram->device_index != device_index) {
1200  continue;
1201  }
1202 
1203  if (!frame_data) {
1204  // fetch pointer to transmit socket buffer
1205  frame_data =
1206  ec_device_tx_data(&master->devices[device_index]);
1207  cur_data = frame_data + EC_FRAME_HEADER_SIZE;
1208  }
1209 
1210  // does the current datagram fit in the frame?
1211  datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size
1213  if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) {
1214  more_datagrams_waiting = 1;
1215  break;
1216  }
1217 
1218  // do not reuse the index of a pending datagram to avoid confusion
1219  // in ec_master_receive_datagrams()
1220  last_index = master->datagram_index;
1221  while (index_in_use(master, master->datagram_index)) {
1222  if (++master->datagram_index == last_index) {
1223  EC_MASTER_ERR(master, "No free datagram index, sending delayed\n");
1224  goto break_send;
1225  }
1226  }
1227  datagram->index = master->datagram_index++;
1228 
1229  list_add_tail(&datagram->sent, &sent_datagrams);
1230 
1231  EC_MASTER_DBG(master, 2, "Adding datagram 0x%02X\n",
1232  datagram->index);
1233 
1234  // set "datagram following" flag in previous datagram
1235  if (follows_word) {
1236  EC_WRITE_U16(follows_word,
1237  EC_READ_U16(follows_word) | 0x8000);
1238  }
1239 
1240  // EtherCAT datagram header
1241  EC_WRITE_U8 (cur_data, datagram->type);
1242  EC_WRITE_U8 (cur_data + 1, datagram->index);
1243  memcpy(cur_data + 2, datagram->address, EC_ADDR_LEN);
1244  EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF);
1245  EC_WRITE_U16(cur_data + 8, 0x0000);
1246  follows_word = cur_data + 6;
1247  cur_data += EC_DATAGRAM_HEADER_SIZE;
1248 
1249  // EtherCAT datagram data
1250  memcpy(cur_data, datagram->data, datagram->data_size);
1251  cur_data += datagram->data_size;
1252 
1253  // EtherCAT datagram footer
1254  EC_WRITE_U16(cur_data, 0x0000); // reset working counter
1255  cur_data += EC_DATAGRAM_FOOTER_SIZE;
1256  }
1257 
1258 break_send:
1259  if (list_empty(&sent_datagrams)) {
1260  EC_MASTER_DBG(master, 2, "nothing to send.\n");
1261  break;
1262  }
1263 
1264  // EtherCAT frame header
1265  EC_WRITE_U16(frame_data, ((cur_data - frame_data
1266  - EC_FRAME_HEADER_SIZE) & 0x7FF) | 0x1000);
1267 
1268  // pad frame
1269  while (cur_data - frame_data < ETH_ZLEN - ETH_HLEN)
1270  EC_WRITE_U8(cur_data++, 0x00);
1271 
1272  EC_MASTER_DBG(master, 2, "frame size: %zu\n", cur_data - frame_data);
1273 
1274  // send frame
1275  ec_device_send(&master->devices[device_index],
1276  cur_data - frame_data);
1277  /* preamble and inter-frame gap */
1278  sent_bytes += ETH_HLEN + cur_data - frame_data + ETH_FCS_LEN + 20;
1279 #ifdef EC_HAVE_CYCLES
1280  cycles_sent = get_cycles();
1281 #endif
1282  jiffies_sent = jiffies;
1283 
1284  // set datagram states and sending timestamps
1285  list_for_each_entry_safe(datagram, next, &sent_datagrams, sent) {
1286  datagram->state = EC_DATAGRAM_SENT;
1287 #ifdef EC_HAVE_CYCLES
1288  datagram->cycles_sent = cycles_sent;
1289 #endif
1290  datagram->jiffies_sent = jiffies_sent;
1291  datagram->app_time_sent = master->app_time;
1292  list_del_init(&datagram->sent); // empty list of sent datagrams
1293  }
1294 
1295  frame_count++;
1296  }
1297  while (more_datagrams_waiting && frame_count < EC_TX_RING_SIZE);
1298 
1299 #ifdef EC_HAVE_CYCLES
1300  if (unlikely(master->debug_level > 1)) {
1301  cycles_end = get_cycles();
1302  EC_MASTER_DBG(master, 0, "%s()"
1303  " sent %u frames in %uus.\n", __func__, frame_count,
1304  (unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz);
1305  }
1306 #endif
1307  return sent_bytes;
1308 }
1309 
1310 /*****************************************************************************/
1311 
1319  ec_master_t *master,
1320  ec_device_t *device,
1321  const uint8_t *frame_data,
1322  size_t size
1323  )
1324 {
1325  size_t frame_size, data_size;
1326  uint8_t datagram_type, datagram_index, datagram_mbox_prot;
1327 #ifdef EC_EOE
1328  uint8_t eoe_type;
1329 #endif
1330  unsigned int cmd_follows, datagram_slave_addr, datagram_offset_addr, datagram_wc, matched;
1331  const uint8_t *cur_data;
1332  ec_datagram_t *datagram;
1333  ec_slave_t *slave;
1334 
1335  if (unlikely(size < EC_FRAME_HEADER_SIZE)) {
1336  if (master->debug_level || FORCE_OUTPUT_CORRUPTED) {
1337  EC_MASTER_DBG(master, 0, "Corrupted frame received"
1338  " on %s (size %zu < %u byte):\n",
1339  device->dev->name, size, EC_FRAME_HEADER_SIZE);
1340  ec_print_data(frame_data, size);
1341  }
1342  master->stats.corrupted++;
1343 #ifdef EC_RT_SYSLOG
1344  ec_master_output_stats(master);
1345 #endif
1346  return;
1347  }
1348 
1349  cur_data = frame_data;
1350 
1351  // check length of entire frame
1352  frame_size = EC_READ_U16(cur_data) & 0x07FF;
1353  cur_data += EC_FRAME_HEADER_SIZE;
1354 
1355  if (unlikely(frame_size > size)) {
1356  if (master->debug_level || FORCE_OUTPUT_CORRUPTED) {
1357  EC_MASTER_DBG(master, 0, "Corrupted frame received"
1358  " on %s (invalid frame size %zu for "
1359  "received size %zu):\n", device->dev->name,
1360  frame_size, size);
1361  ec_print_data(frame_data, size);
1362  }
1363  master->stats.corrupted++;
1364 #ifdef EC_RT_SYSLOG
1365  ec_master_output_stats(master);
1366 #endif
1367  return;
1368  }
1369 
1370  cmd_follows = 1;
1371  while (cmd_follows) {
1372  // process datagram header
1373  datagram_type = EC_READ_U8 (cur_data);
1374  datagram_index = EC_READ_U8 (cur_data + 1);
1375  datagram_slave_addr = EC_READ_U16(cur_data + 2);
1376  datagram_offset_addr = EC_READ_U16(cur_data + 4);
1377  data_size = EC_READ_U16(cur_data + 6) & 0x07FF;
1378  cmd_follows = EC_READ_U16(cur_data + 6) & 0x8000;
1379  cur_data += EC_DATAGRAM_HEADER_SIZE;
1380 
1381  if (unlikely(cur_data - frame_data
1382  + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) {
1383  if (master->debug_level || FORCE_OUTPUT_CORRUPTED) {
1384  EC_MASTER_DBG(master, 0, "Corrupted frame received"
1385  " on %s (invalid data size %zu):\n",
1386  device->dev->name, data_size);
1387  ec_print_data(frame_data, size);
1388  }
1389  master->stats.corrupted++;
1390 #ifdef EC_RT_SYSLOG
1391  ec_master_output_stats(master);
1392 #endif
1393  return;
1394  }
1395 
1396  // search for matching datagram in the queue
1397  matched = 0;
1398  list_for_each_entry(datagram, &master->datagram_queue, queue) {
1399  if (datagram->index == datagram_index
1400  && datagram->state == EC_DATAGRAM_SENT
1401  && datagram->type == datagram_type
1402  && datagram->data_size == data_size) {
1403  matched = 1;
1404  break;
1405  }
1406  }
1407 
1408  // no matching datagram was found
1409  if (!matched) {
1410  master->stats.unmatched++;
1411 #ifdef EC_RT_SYSLOG
1412  ec_master_output_stats(master);
1413 #endif
1414 
1415  if (unlikely(master->debug_level > 0)) {
1416  EC_MASTER_DBG(master, 0, "UNMATCHED datagram:\n");
1418  EC_DATAGRAM_HEADER_SIZE + data_size
1420 #ifdef EC_DEBUG_RING
1421  ec_device_debug_ring_print(&master->devices[EC_DEVICE_MAIN]);
1422 #endif
1423  }
1424 
1425  cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;
1426  continue;
1427  }
1428 
1429  if (datagram->type != EC_DATAGRAM_APWR &&
1430  datagram->type != EC_DATAGRAM_FPWR &&
1431  datagram->type != EC_DATAGRAM_BWR &&
1432  datagram->type != EC_DATAGRAM_LWR) {
1433 
1434  // common mailbox dispatcher for mailboxes read using the physical slave address
1435  if (datagram->type == EC_DATAGRAM_FPRD) {
1436  datagram_wc = EC_READ_U16(cur_data + data_size);
1437  if (datagram_wc) {
1438  if (master->slaves != NULL) {
1439  for (slave = master->slaves; slave < master->slaves + master->slave_count; slave++) {
1440  if (slave->station_address == datagram_slave_addr) {
1441  break;
1442  }
1443  }
1444  if (slave->station_address == datagram_slave_addr) {
1445  if (slave->configured_tx_mailbox_offset != 0) {
1446  if (datagram_offset_addr == slave->configured_tx_mailbox_offset) {
1447  if (slave->valid_mbox_data) {
1448  // check if the mailbox header slave address is the
1449  // MBox Gateway addr offset above the slave position, and
1450  // a valid MBox Gateway address
1451  // Note: the datagram station address is the slave position + 1
1452  // Note: the EL6614 EoE module does not fill in the MailBox Header
1453  // Address value in the EoE response. Other modules / protocols
1454  // may do the same.
1455  if (unlikely(
1456  (EC_READ_U16(cur_data + 2) == datagram_slave_addr + EC_MBG_SLAVE_ADDR_OFFSET - 1) &&
1457  (EC_READ_U16(cur_data + 2) >= EC_MBG_SLAVE_ADDR_OFFSET) )) {
1458  // EtherCAT Mailbox Gateway response
1459  if ((slave->mbox_mbg_data.data) && (data_size <= slave->mbox_mbg_data.data_size)) {
1460  memcpy(slave->mbox_mbg_data.data, cur_data, data_size);
1461  slave->mbox_mbg_data.payload_size = data_size;
1462  }
1463  } else {
1464  datagram_mbox_prot = EC_READ_U8(cur_data + 5) & 0x0F;
1465  switch (datagram_mbox_prot) {
1466 #ifdef EC_EOE
1467  case EC_MBOX_TYPE_EOE:
1468  // check EOE type and store in correct handlers mbox data cache
1469  eoe_type = EC_READ_U8(cur_data + 6) & 0x0F;
1470 
1471  switch (eoe_type) {
1472 
1473  case EC_EOE_TYPE_FRAME_FRAG:
1474  // EoE Frame Fragment handler
1475  if ((slave->mbox_eoe_frag_data.data) && (data_size <= slave->mbox_eoe_frag_data.data_size)) {
1476  memcpy(slave->mbox_eoe_frag_data.data, cur_data, data_size);
1477  slave->mbox_eoe_frag_data.payload_size = data_size;
1478  }
1479  break;
1480  case EC_EOE_TYPE_INIT_RES:
1481  // EoE Init / Set IP response handler
1482  if ((slave->mbox_eoe_init_data.data) && (data_size <= slave->mbox_eoe_init_data.data_size)) {
1483  memcpy(slave->mbox_eoe_init_data.data, cur_data, data_size);
1484  slave->mbox_eoe_init_data.payload_size = data_size;
1485  }
1486  break;
1487  default:
1488  EC_MASTER_DBG(master, 1, "Unhandled EoE protocol type from slave: %u Protocol: %u, Type: %x\n",
1489  datagram_slave_addr, datagram_mbox_prot, eoe_type);
1490  // copy instead received data into the datagram memory.
1491  memcpy(datagram->data, cur_data, data_size);
1492  break;
1493  }
1494  break;
1495 #endif
1496  case EC_MBOX_TYPE_COE:
1497  if ((slave->mbox_coe_data.data) && (data_size <= slave->mbox_coe_data.data_size)) {
1498  memcpy(slave->mbox_coe_data.data, cur_data, data_size);
1499  slave->mbox_coe_data.payload_size = data_size;
1500  }
1501  break;
1502  case EC_MBOX_TYPE_FOE:
1503  if ((slave->mbox_foe_data.data) && (data_size <= slave->mbox_foe_data.data_size)) {
1504  memcpy(slave->mbox_foe_data.data, cur_data, data_size);
1505  slave->mbox_foe_data.payload_size = data_size;
1506  }
1507  break;
1508  case EC_MBOX_TYPE_SOE:
1509  if ((slave->mbox_soe_data.data) && (data_size <= slave->mbox_soe_data.data_size)) {
1510  memcpy(slave->mbox_soe_data.data, cur_data, data_size);
1511  slave->mbox_soe_data.payload_size = data_size;
1512  }
1513  break;
1514  case EC_MBOX_TYPE_VOE:
1515  if ((slave->mbox_voe_data.data) && (data_size <= slave->mbox_voe_data.data_size)) {
1516  memcpy(slave->mbox_voe_data.data, cur_data, data_size);
1517  slave->mbox_voe_data.payload_size = data_size;
1518  }
1519  break;
1520  default:
1521  EC_MASTER_DBG(master, 1, "Unknown mailbox protocol from slave: %u Protocol: %u\n", datagram_slave_addr, datagram_mbox_prot);
1522  // copy instead received data into the datagram memory.
1523  memcpy(datagram->data, cur_data, data_size);
1524  break;
1525  }
1526  }
1527  } else {
1528  // copy instead received data into the datagram memory.
1529  memcpy(datagram->data, cur_data, data_size);
1530  }
1531  } else {
1532  // copy instead received data into the datagram memory.
1533  memcpy(datagram->data, cur_data, data_size);
1534  }
1535  } else {
1536  // copy instead received data into the datagram memory.
1537  memcpy(datagram->data, cur_data, data_size);
1538  }
1539  } else {
1540  EC_MASTER_DBG(master, 1, "No slave matching datagram slave address: %u\n", datagram_slave_addr);
1541  }
1542  } else {
1543  EC_MASTER_DBG(master, 1, "No configured slaves!\n");
1544  // copy instead received data into the datagram memory.
1545  memcpy(datagram->data, cur_data, data_size);
1546  }
1547  } else {
1548  // copy instead received data into the datagram memory.
1549  memcpy(datagram->data, cur_data, data_size);
1550  }
1551  } else {
1552  // copy instead received data into the datagram memory.
1553  memcpy(datagram->data, cur_data, data_size);
1554  }
1555  }
1556  cur_data += data_size;
1557 
1558  // set the datagram's working counter
1559  datagram->working_counter = EC_READ_U16(cur_data);
1560  cur_data += EC_DATAGRAM_FOOTER_SIZE;
1561 
1562 #ifdef EC_HAVE_CYCLES
1563  datagram->cycles_received =
1564  master->devices[EC_DEVICE_MAIN].cycles_poll;
1565 #endif
1566  datagram->jiffies_received =
1568 
1569  barrier(); /* reordering might lead to races */
1570 
1571  // dequeue the received datagram
1572  datagram->state = EC_DATAGRAM_RECEIVED;
1573  list_del_init(&datagram->queue);
1574  }
1575 }
1576 
1577 /*****************************************************************************/
1578 
1585 {
1586  if (unlikely(jiffies - master->stats.output_jiffies >= HZ)) {
1587  if (!master->scan_busy || (master->debug_level > 0)) {
1588  master->stats.output_jiffies = jiffies;
1589  if (master->stats.timeouts) {
1590  EC_MASTER_WARN(master, "%u datagram%s TIMED OUT!\n",
1591  master->stats.timeouts,
1592  master->stats.timeouts == 1 ? "" : "s");
1593  master->stats.timeouts = 0;
1594  }
1595  if (master->stats.corrupted) {
1596  EC_MASTER_WARN(master, "%u frame%s CORRUPTED!\n",
1597  master->stats.corrupted,
1598  master->stats.corrupted == 1 ? "" : "s");
1599  master->stats.corrupted = 0;
1600  }
1601  if (master->stats.unmatched) {
1602  EC_MASTER_WARN(master, "%u datagram%s UNMATCHED!\n",
1603  master->stats.unmatched,
1604  master->stats.unmatched == 1 ? "" : "s");
1605  master->stats.unmatched = 0;
1606  }
1607  }
1608  }
1609 }
1610 
1611 /*****************************************************************************/
1612 
1616  ec_master_t *master
1617  )
1618 {
1619  unsigned int i;
1620 
1621  // zero frame statistics
1622  master->device_stats.tx_count = 0;
1623  master->device_stats.last_tx_count = 0;
1624  master->device_stats.rx_count = 0;
1625  master->device_stats.last_rx_count = 0;
1626  master->device_stats.tx_bytes = 0;
1627  master->device_stats.last_tx_bytes = 0;
1628  master->device_stats.rx_bytes = 0;
1629  master->device_stats.last_rx_bytes = 0;
1630  master->device_stats.last_loss = 0;
1631 
1632  for (i = 0; i < EC_RATE_COUNT; i++) {
1633  master->device_stats.tx_frame_rates[i] = 0;
1634  master->device_stats.rx_frame_rates[i] = 0;
1635  master->device_stats.tx_byte_rates[i] = 0;
1636  master->device_stats.rx_byte_rates[i] = 0;
1637  master->device_stats.loss_rates[i] = 0;
1638  }
1639 
1640  master->device_stats.jiffies = 0;
1641 }
1642 
1643 /*****************************************************************************/
1644 
1648  ec_master_t *master
1649  )
1650 {
1651  ec_device_stats_t *s = &master->device_stats;
1652  s32 tx_frame_rate, rx_frame_rate, tx_byte_rate, rx_byte_rate, loss_rate;
1653  u64 loss;
1654  unsigned int i, dev_idx;
1655 
1656  // frame statistics
1657  if (likely(jiffies - s->jiffies < HZ)) {
1658  return;
1659  }
1660 
1661  tx_frame_rate = (s->tx_count - s->last_tx_count) * 1000;
1662  rx_frame_rate = (s->rx_count - s->last_rx_count) * 1000;
1663  tx_byte_rate = s->tx_bytes - s->last_tx_bytes;
1664  rx_byte_rate = s->rx_bytes - s->last_rx_bytes;
1665  loss = s->tx_count - s->rx_count;
1666  loss_rate = (loss - s->last_loss) * 1000;
1667 
1668  /* Low-pass filter:
1669  * Y_n = y_(n - 1) + T / tau * (x - y_(n - 1)) | T = 1
1670  * -> Y_n += (x - y_(n - 1)) / tau
1671  */
1672  for (i = 0; i < EC_RATE_COUNT; i++) {
1673  s32 n = rate_intervals[i];
1674  s->tx_frame_rates[i] += (tx_frame_rate - s->tx_frame_rates[i]) / n;
1675  s->rx_frame_rates[i] += (rx_frame_rate - s->rx_frame_rates[i]) / n;
1676  s->tx_byte_rates[i] += (tx_byte_rate - s->tx_byte_rates[i]) / n;
1677  s->rx_byte_rates[i] += (rx_byte_rate - s->rx_byte_rates[i]) / n;
1678  s->loss_rates[i] += (loss_rate - s->loss_rates[i]) / n;
1679  }
1680 
1681  s->last_tx_count = s->tx_count;
1682  s->last_rx_count = s->rx_count;
1683  s->last_tx_bytes = s->tx_bytes;
1684  s->last_rx_bytes = s->rx_bytes;
1685  s->last_loss = loss;
1686 
1687  for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
1688  dev_idx++) {
1689  ec_device_update_stats(&master->devices[dev_idx]);
1690  }
1691 
1692  s->jiffies = jiffies;
1693 }
1694 
1695 /*****************************************************************************/
1696 
1697 #ifdef EC_USE_HRTIMER
1698 
1699 /*
1700  * Sleep related functions:
1701  */
1702 static enum hrtimer_restart ec_master_nanosleep_wakeup(struct hrtimer *timer)
1703 {
1704  struct hrtimer_sleeper *t =
1705  container_of(timer, struct hrtimer_sleeper, timer);
1706  struct task_struct *task = t->task;
1707 
1708  t->task = NULL;
1709  if (task)
1710  wake_up_process(task);
1711 
1712  return HRTIMER_NORESTART;
1713 }
1714 
1715 /*****************************************************************************/
1716 
1717 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
1718 
1719 /* compatibility with new hrtimer interface */
1720 static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer)
1721 {
1722  return timer->expires;
1723 }
1724 
1725 /*****************************************************************************/
1726 
1727 static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
1728 {
1729  timer->expires = time;
1730 }
1731 
1732 #endif
1733 
1734 /*****************************************************************************/
1735 
1736 void ec_master_nanosleep(const unsigned long nsecs)
1737 {
1738  struct hrtimer_sleeper t;
1739  enum hrtimer_mode mode = HRTIMER_MODE_REL;
1740 
1741  hrtimer_init(&t.timer, CLOCK_MONOTONIC, mode);
1742  t.timer.function = ec_master_nanosleep_wakeup;
1743  t.task = current;
1744 #ifdef CONFIG_HIGH_RES_TIMERS
1745 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
1746  t.timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_RESTART;
1747 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
1748  t.timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
1749 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 28)
1750  t.timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
1751 #endif
1752 #endif
1753  hrtimer_set_expires(&t.timer, ktime_set(0, nsecs));
1754 
1755  do {
1756  set_current_state(TASK_INTERRUPTIBLE);
1757  hrtimer_start(&t.timer, hrtimer_get_expires(&t.timer), mode);
1758 
1759  if (likely(t.task))
1760  schedule();
1761 
1762  hrtimer_cancel(&t.timer);
1763  mode = HRTIMER_MODE_ABS;
1764 
1765  } while (t.task && !signal_pending(current));
1766 }
1767 
1768 #endif // EC_USE_HRTIMER
1769 
1770 /*****************************************************************************/
1771 
1775  ec_master_t *master
1776  )
1777 {
1778  ec_datagram_t *datagram;
1779  ec_fsm_slave_t *fsm, *next;
1780  unsigned int count = 0;
1781 
1782  list_for_each_entry_safe(fsm, next, &master->fsm_exec_list, list) {
1783  if (!fsm->datagram) {
1784  EC_MASTER_WARN(master, "Slave %s-%u FSM has zero datagram."
1785  "This is a bug!\n", ec_device_names[fsm->slave->device_index!=0],
1786  fsm->slave->ring_position);
1787  list_del_init(&fsm->list);
1788  master->fsm_exec_count--;
1789  return;
1790  }
1791 
1792  if (fsm->datagram->state == EC_DATAGRAM_INIT ||
1793  fsm->datagram->state == EC_DATAGRAM_QUEUED ||
1794  fsm->datagram->state == EC_DATAGRAM_SENT) {
1795  // previous datagram was not sent or received yet.
1796  // wait until next thread execution
1797  return;
1798  }
1799 
1800  datagram = ec_master_get_external_datagram(master);
1801  if (!datagram) {
1802  // no free datagrams at the moment
1803  EC_MASTER_WARN(master, "No free datagram during"
1804  " slave FSM execution. This is a bug!\n");
1805  continue;
1806  }
1807 
1808 #if DEBUG_INJECT
1809  EC_MASTER_DBG(master, 1, "Executing slave %s-%u FSM.\n",
1811  fsm->slave->ring_position);
1812 #endif
1813  if (ec_fsm_slave_exec(fsm, datagram)) {
1814  if (datagram->state != EC_DATAGRAM_INVALID) {
1815  // FSM consumed datagram
1816 #if DEBUG_INJECT
1817  EC_MASTER_DBG(master, 1, "FSM consumed datagram %s\n",
1818  datagram->name);
1819 #endif
1820  master->ext_ring_idx_fsm =
1821  (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
1822  }
1823  }
1824  else {
1825  // FSM finished
1826  list_del_init(&fsm->list);
1827  master->fsm_exec_count--;
1828 #if DEBUG_INJECT
1829  EC_MASTER_DBG(master, 1, "FSM finished. %u remaining.\n",
1830  master->fsm_exec_count);
1831 #endif
1832  }
1833  }
1834 
1835  while (master->fsm_exec_count < EC_EXT_RING_SIZE / 2
1836  && count < master->slave_count) {
1837 
1838  if (ec_fsm_slave_is_ready(&master->fsm_slave->fsm)) {
1839  datagram = ec_master_get_external_datagram(master);
1840 
1841  if (ec_fsm_slave_exec(&master->fsm_slave->fsm, datagram)) {
1842  if (datagram->state != EC_DATAGRAM_INVALID) {
1843  master->ext_ring_idx_fsm =
1844  (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
1845  }
1846  list_add_tail(&master->fsm_slave->fsm.list,
1847  &master->fsm_exec_list);
1848  master->fsm_exec_count++;
1849 #if DEBUG_INJECT
1850  EC_MASTER_DBG(master, 1, "New slave %s-%u FSM"
1851  " consumed datagram %s, now %u FSMs in list.\n",
1852  ec_device_names[master->fsm_slave->device_index!=0],
1853  master->fsm_slave->ring_position, datagram->name,
1854  master->fsm_exec_count);
1855 #endif
1856  }
1857  }
1858 
1859  master->fsm_slave++;
1860  if (master->fsm_slave >= master->slaves + master->slave_count) {
1861  master->fsm_slave = master->slaves;
1862  }
1863  count++;
1864  }
1865 }
1866 
1867 /*****************************************************************************/
1868 
1871 static int ec_master_idle_thread(void *priv_data)
1872 {
1873  ec_master_t *master = (ec_master_t *) priv_data;
1874  int fsm_exec;
1875  size_t sent_bytes;
1876 
1877  // send interval in IDLE phase
1878  ec_master_set_send_interval(master, 1000000 / HZ);
1879 
1880  EC_MASTER_DBG(master, 1, "Idle thread running with send interval = %u us,"
1881  " max data size=%zu\n", master->send_interval,
1882  master->max_queue_size);
1883 
1884  while (!kthread_should_stop()) {
1886 
1887  // receive
1888  ec_lock_down(&master->io_sem);
1889  ecrt_master_receive(master);
1890  ec_lock_up(&master->io_sem);
1891 
1892  // execute master & slave state machines
1893  if (ec_lock_down_interruptible(&master->master_sem)) {
1894  break;
1895  }
1896 
1897  fsm_exec = ec_fsm_master_exec(&master->fsm);
1898 
1899  // idle thread will still be in charge of calling the slave requests
1900  ec_master_exec_slave_fsms(master);
1901 
1902  ec_lock_up(&master->master_sem);
1903 
1904  // queue and send
1905  ec_lock_down(&master->io_sem);
1906  if (fsm_exec) {
1907  ec_master_queue_datagram(master, &master->fsm_datagram);
1908  }
1909  sent_bytes = ecrt_master_send(master);
1910  ec_lock_up(&master->io_sem);
1911 
1912  if (ec_fsm_master_idle(&master->fsm)) {
1913 #ifdef EC_USE_HRTIMER
1914  ec_master_nanosleep(master->send_interval * 1000);
1915 #else
1916  set_current_state(TASK_INTERRUPTIBLE);
1917  schedule_timeout(1);
1918 #endif
1919  } else {
1920 #ifdef EC_USE_HRTIMER
1921  ec_master_nanosleep(
1922  sent_bytes * EC_BYTE_TRANSMISSION_TIME_NS * 6 / 5);
1923 #else
1924  schedule();
1925 #endif
1926  }
1927  }
1928 
1929  EC_MASTER_DBG(master, 1, "Master IDLE thread exiting...\n");
1930 
1931  return 0;
1932 }
1933 
1934 /*****************************************************************************/
1935 
1938 static int ec_master_operation_thread(void *priv_data)
1939 {
1940  ec_master_t *master = (ec_master_t *) priv_data;
1941 
1942  EC_MASTER_DBG(master, 1, "Operation thread running"
1943  " with fsm interval = %u us, max data size=%zu\n",
1944  master->send_interval, master->max_queue_size);
1945 
1946  while (!kthread_should_stop()) {
1948 
1949  if (master->injection_seq_rt == master->injection_seq_fsm) {
1950  // output statistics
1951  ec_master_output_stats(master);
1952 
1953  // execute master & slave state machines
1954  if (ec_lock_down_interruptible(&master->master_sem)) {
1955  break;
1956  }
1957 
1958  if (ec_fsm_master_exec(&master->fsm)) {
1959  // Inject datagrams (let the RT thread queue them, see
1960  // ecrt_master_send())
1961  master->injection_seq_fsm++;
1962  }
1963 
1964  // if rt_slave_requests is true and the slaves are available
1965  // this will be handled by the app explicitly calling
1966  // ecrt_master_exec_slave_request()
1967  if (!master->rt_slave_requests || !master->rt_slaves_available) {
1968  ec_master_exec_slave_fsms(master);
1969  }
1970 
1971  ec_lock_up(&master->master_sem);
1972  }
1973 
1974 #ifdef EC_USE_HRTIMER
1975  // the op thread should not work faster than the sending RT thread
1976  ec_master_nanosleep(master->send_interval * 1000);
1977 #else
1978  if (ec_fsm_master_idle(&master->fsm)) {
1979  set_current_state(TASK_INTERRUPTIBLE);
1980  schedule_timeout(1);
1981  }
1982  else {
1983  schedule();
1984  }
1985 #endif
1986  }
1987 
1988  EC_MASTER_DBG(master, 1, "Master OP thread exiting...\n");
1989  return 0;
1990 }
1991 
1992 /*****************************************************************************/
1993 
1994 #ifdef EC_EOE
1995 
1998 {
1999  struct sched_param param = { .sched_priority = 0 };
2000 
2001  if (master->eoe_thread) {
2002  EC_MASTER_WARN(master, "EoE already running!\n");
2003  return;
2004  }
2005 
2006  if (list_empty(&master->eoe_handlers)) {
2007  return;
2008  }
2009 
2010  if (!master->send_cb || !master->receive_cb) {
2011  EC_MASTER_WARN(master, "EoE External processing"
2012  " required!\n");
2013  return;
2014  }
2015 
2016  EC_MASTER_INFO(master, "Starting EoE thread.\n");
2017 
2018  master->eoe_thread = kthread_run(ec_master_eoe_thread, master,
2019  "EtherCAT-EoE");
2020  if (IS_ERR(master->eoe_thread)) {
2021  int err = (int) PTR_ERR(master->eoe_thread);
2022  EC_MASTER_ERR(master, "Failed to start EoE thread (error %i)!\n",
2023  err);
2024  master->eoe_thread = NULL;
2025  return;
2026  }
2027 
2028  sched_setscheduler(master->eoe_thread, SCHED_NORMAL, &param);
2029  set_user_nice(master->eoe_thread, 0);
2030 }
2031 
2032 /*****************************************************************************/
2033 
2037 {
2038  if (master->eoe_thread) {
2039  EC_MASTER_INFO(master, "Stopping EoE thread.\n");
2040 
2041  kthread_stop(master->eoe_thread);
2042  master->eoe_thread = NULL;
2043  EC_MASTER_INFO(master, "EoE thread exited.\n");
2044  }
2045 }
2046 
2047 /*****************************************************************************/
2048 
2049 #ifdef EC_RTDM
2050 
2056 int ec_master_eoe_is_open(ec_master_t *master )
2057 {
2058  ec_eoe_t *eoe;
2059 
2060  // check that eoe is not already being processed by the master
2061  // and that we can currently process EoE
2062  if ( (master->phase != EC_OPERATION) || master->eoe_thread ||
2063  !master->rt_slaves_available ) {
2064  // protocol not available
2065  return -ENOPROTOOPT;
2066  }
2067 
2068  ec_lock_down(&master->master_sem);
2069  list_for_each_entry(eoe, &master->eoe_handlers, list) {
2070  if (ec_eoe_is_open(eoe)) {
2071  ec_lock_up(&master->master_sem);
2072  return 1;
2073  }
2074  }
2075  ec_lock_up(&master->master_sem);
2076 
2077  return 0;
2078 }
2079 
2080 /*****************************************************************************/
2081 
2087 int ec_master_eoe_process(ec_master_t *master )
2088 {
2089  ec_eoe_t *eoe;
2090  int sth_to_send = 0;
2091  int sth_pending = 0;
2092 
2093  // check that eoe is not already being processed by the master
2094  if (master->eoe_thread) {
2095  return 0;
2096  }
2097 
2098  // actual EoE processing
2099  ec_lock_down(&master->master_sem);
2100  list_for_each_entry(eoe, &master->eoe_handlers, list) {
2101  if ( eoe->slave &&
2102  ( (eoe->slave->current_state == EC_SLAVE_STATE_PREOP) ||
2104  (eoe->slave->current_state == EC_SLAVE_STATE_OP) ) ) {
2105  ec_eoe_run(eoe);
2106  if (eoe->queue_datagram) {
2107  sth_to_send = EOE_STH_TO_SEND;
2108  }
2109  if (!ec_eoe_is_idle(eoe)) {
2110  sth_pending = EOE_STH_PENDING;
2111  }
2112  }
2113  }
2114 
2115  if (sth_to_send) {
2116  list_for_each_entry(eoe, &master->eoe_handlers, list) {
2117  ec_eoe_queue(eoe);
2118  }
2119  }
2120  ec_lock_up(&master->master_sem);
2121 
2122  return sth_to_send + sth_pending;
2123 }
2124 
2125 #endif
2126 
2127 /*****************************************************************************/
2128 
2131 static int ec_master_eoe_thread(void *priv_data)
2132 {
2133  ec_master_t *master = (ec_master_t *) priv_data;
2134  ec_eoe_t *eoe;
2135  unsigned int none_open, sth_to_send, all_idle;
2136 
2137  EC_MASTER_DBG(master, 1, "EoE thread running.\n");
2138 
2139  while (!kthread_should_stop()) {
2140  none_open = 1;
2141  all_idle = 1;
2142 
2143  ec_lock_down(&master->master_sem);
2144  list_for_each_entry(eoe, &master->eoe_handlers, list) {
2145  if (ec_eoe_is_open(eoe)) {
2146  none_open = 0;
2147  break;
2148  }
2149  }
2150  ec_lock_up(&master->master_sem);
2151 
2152  if (none_open) {
2153  goto schedule;
2154  }
2155 
2156  // receive datagrams
2157  master->receive_cb(master->cb_data);
2158 
2159  // actual EoE processing
2160  ec_lock_down(&master->master_sem);
2161  sth_to_send = 0;
2162  list_for_each_entry(eoe, &master->eoe_handlers, list) {
2163  if ( eoe->slave &&
2164  ( (eoe->slave->current_state == EC_SLAVE_STATE_PREOP) ||
2166  (eoe->slave->current_state == EC_SLAVE_STATE_OP) ) ) {
2167  ec_eoe_run(eoe);
2168  if (eoe->queue_datagram) {
2169  sth_to_send = 1;
2170  }
2171  if (!ec_eoe_is_idle(eoe)) {
2172  all_idle = 0;
2173  }
2174  }
2175  }
2176  ec_lock_up(&master->master_sem);
2177 
2178  if (sth_to_send) {
2179  ec_lock_down(&master->master_sem);
2180  list_for_each_entry(eoe, &master->eoe_handlers, list) {
2181  ec_eoe_queue(eoe);
2182  }
2183  ec_lock_up(&master->master_sem);
2184 
2185  // (try to) send datagrams
2186  master->send_cb(master->cb_data);
2187  }
2188 
2189 schedule:
2190  if (all_idle) {
2191  set_current_state(TASK_INTERRUPTIBLE);
2192  schedule_timeout(1);
2193  } else {
2194  schedule();
2195  }
2196  }
2197 
2198  EC_MASTER_DBG(master, 1, "EoE thread exiting...\n");
2199  return 0;
2200 }
2201 #endif
2202 
2203 /*****************************************************************************/
2204 
2208  ec_master_t *master
2209  )
2210 {
2211  ec_slave_config_t *sc;
2212 
2213  list_for_each_entry(sc, &master->configs, list) {
2215  }
2216 }
2217 
2218 /*****************************************************************************/
2219 
2223  ec_master_t *master
2224  )
2225 {
2226  ec_slave_config_t *sc;
2227 
2228  list_for_each_entry(sc, &master->configs, list) {
2230  }
2231 }
2232 
2233 /*****************************************************************************/
2234 
2238 #define EC_FIND_SLAVE \
2239  do { \
2240  if (alias) { \
2241  for (; slave < master->slaves + master->slave_count; \
2242  slave++) { \
2243  if (slave->effective_alias == alias) \
2244  break; \
2245  } \
2246  if (slave == master->slaves + master->slave_count) \
2247  return NULL; \
2248  } \
2249  \
2250  slave += position; \
2251  if (slave < master->slaves + master->slave_count) { \
2252  return slave; \
2253  } else { \
2254  return NULL; \
2255  } \
2256  } while (0)
2257 
2263  ec_master_t *master,
2264  uint16_t alias,
2265  uint16_t position
2266  )
2267 {
2268  ec_slave_t *slave = master->slaves;
2269  EC_FIND_SLAVE;
2270 }
2271 
2279  const ec_master_t *master,
2280  uint16_t alias,
2281  uint16_t position
2282  )
2283 {
2284  const ec_slave_t *slave = master->slaves;
2285  EC_FIND_SLAVE;
2286 }
2287 
2288 /*****************************************************************************/
2289 
2295  const ec_master_t *master
2296  )
2297 {
2298  const ec_slave_config_t *sc;
2299  unsigned int count = 0;
2300 
2301  list_for_each_entry(sc, &master->configs, list) {
2302  count++;
2303  }
2304 
2305  return count;
2306 }
2307 
2308 /*****************************************************************************/
2309 
2313 #define EC_FIND_CONFIG \
2314  do { \
2315  list_for_each_entry(sc, &master->configs, list) { \
2316  if (pos--) \
2317  continue; \
2318  return sc; \
2319  } \
2320  return NULL; \
2321  } while (0)
2322 
2328  const ec_master_t *master,
2329  unsigned int pos
2330  )
2331 {
2332  ec_slave_config_t *sc;
2334 }
2335 
2343  const ec_master_t *master,
2344  unsigned int pos
2345  )
2346 {
2347  const ec_slave_config_t *sc;
2349 }
2350 
2351 /*****************************************************************************/
2352 
2358  const ec_master_t *master
2359  )
2360 {
2361  const ec_domain_t *domain;
2362  unsigned int count = 0;
2363 
2364  list_for_each_entry(domain, &master->domains, list) {
2365  count++;
2366  }
2367 
2368  return count;
2369 }
2370 
2371 /*****************************************************************************/
2372 
2376 #define EC_FIND_DOMAIN \
2377  do { \
2378  list_for_each_entry(domain, &master->domains, list) { \
2379  if (index--) \
2380  continue; \
2381  return domain; \
2382  } \
2383  \
2384  return NULL; \
2385  } while (0)
2386 
2392  ec_master_t *master,
2393  unsigned int index
2394  )
2395 {
2396  ec_domain_t *domain;
2398 }
2399 
2407  const ec_master_t *master,
2408  unsigned int index
2409  )
2410 {
2411  const ec_domain_t *domain;
2413 }
2414 
2415 /*****************************************************************************/
2416 
2417 #ifdef EC_EOE
2418 
2424  const ec_master_t *master
2425  )
2426 {
2427  const ec_eoe_t *eoe;
2428  unsigned int count = 0;
2429 
2430  list_for_each_entry(eoe, &master->eoe_handlers, list) {
2431  count++;
2432  }
2433 
2434  return count;
2435 }
2436 
2437 /*****************************************************************************/
2438 
2446  const ec_master_t *master,
2447  uint16_t index
2448  )
2449 {
2450  const ec_eoe_t *eoe;
2451 
2452  list_for_each_entry(eoe, &master->eoe_handlers, list) {
2453  if (index--)
2454  continue;
2455  return eoe;
2456  }
2457 
2458  return NULL;
2459 }
2460 
2461 #endif
2462 
2463 /*****************************************************************************/
2464 
2471  ec_master_t *master,
2472  unsigned int level
2473  )
2474 {
2475  if (level > 2) {
2476  EC_MASTER_ERR(master, "Invalid debug level %u!\n", level);
2477  return -EINVAL;
2478  }
2479 
2480  if (level != master->debug_level) {
2481  master->debug_level = level;
2482  EC_MASTER_INFO(master, "Master debug level set to %u.\n",
2483  master->debug_level);
2484  }
2485 
2486  return 0;
2487 }
2488 
2489 /*****************************************************************************/
2490 
2494  ec_master_t *master
2495  )
2496 {
2497  ec_slave_t *slave, *ref = NULL;
2498 
2499  if (master->dc_ref_config) {
2500  // Check application-selected reference clock
2501  slave = master->dc_ref_config->slave;
2502 
2503  if (slave) {
2504  if (slave->base_dc_supported && slave->has_dc_system_time) {
2505  ref = slave;
2506  EC_MASTER_INFO(master, "Using slave %s-%u as application selected"
2507  " DC reference clock.\n", ec_device_names[slave->device_index!=0],
2508  ref->ring_position);
2509  }
2510  else {
2511  EC_MASTER_WARN(master, "Application selected slave %s-%u can not"
2512  " act as a DC reference clock!", ec_device_names[slave->device_index!=0],
2513  slave->ring_position);
2514  }
2515  }
2516  else {
2517  EC_MASTER_WARN(master, "Application selected DC reference clock"
2518  " config (%u-%u) has no slave attached!\n",
2519  master->dc_ref_config->alias,
2520  master->dc_ref_config->position);
2521  }
2522  }
2523 
2524  if (!ref) {
2525  // Use first slave with DC support as reference clock
2526  for (slave = master->slaves;
2527  slave < master->slaves + master->slave_count;
2528  slave++) {
2529  if (slave->base_dc_supported && slave->has_dc_system_time) {
2530  ref = slave;
2531  break;
2532  }
2533  }
2534 
2535  }
2536 
2537  master->dc_ref_clock = ref;
2538 
2539  if (ref) {
2540  EC_MASTER_INFO(master, "Using slave %s-%u as DC reference clock.\n",
2541  ec_device_names[ref->device_index!=0], ref->ring_position);
2542  }
2543  else {
2544  EC_MASTER_INFO(master, "No DC reference clock found.\n");
2545  }
2546 
2547  // These calls always succeed, because the
2548  // datagrams have been pre-allocated.
2550  ref ? ref->station_address : 0xffff, 0x0910, 4);
2552  ref ? ref->station_address : 0xffff, 0x0910, 4);
2554  ref ? ref->station_address : 0xffff, 0x0910, 8);
2555 }
2556 
2557 /*****************************************************************************/
2558 
2564  ec_master_t *master,
2565  ec_slave_t *upstream_slave,
2566  unsigned int *slave_position
2567  )
2568 {
2569  ec_slave_t *slave = master->slaves + *slave_position;
2570  unsigned int port_index;
2571  int ret;
2572 
2573  static const unsigned int next_table[EC_MAX_PORTS] = {
2574  3, 2, 0, 1
2575  };
2576 
2577  slave->ports[slave->upstream_port].next_slave = upstream_slave;
2578 
2579  port_index = next_table[slave->upstream_port];
2580  while (port_index != slave->upstream_port) {
2581  if (!slave->ports[port_index].link.loop_closed) {
2582  *slave_position = *slave_position + 1;
2583  if (*slave_position < master->slave_count) {
2584  slave->ports[port_index].next_slave =
2585  master->slaves + *slave_position;
2586  ret = ec_master_calc_topology_rec(master,
2587  slave, slave_position);
2588  if (ret) {
2589  return ret;
2590  }
2591  } else {
2592  return -1;
2593  }
2594  }
2595 
2596  port_index = next_table[port_index];
2597  }
2598 
2599  return 0;
2600 }
2601 
2602 /*****************************************************************************/
2603 
2607  ec_master_t *master
2608  )
2609 {
2610  unsigned int slave_position = 0;
2611  ec_slave_t *slave;
2612 
2613  if (master->slave_count == 0)
2614  return;
2615 
2616  for (slave = master->slaves;
2617  slave < master->slaves + master->slave_count;
2618  slave++) {
2620  }
2621 
2622  if (ec_master_calc_topology_rec(master, NULL, &slave_position))
2623  EC_MASTER_ERR(master, "Failed to calculate bus topology.\n");
2624 }
2625 
2626 /*****************************************************************************/
2627 
2631  ec_master_t *master
2632  )
2633 {
2634  ec_slave_t *slave;
2635 
2636  for (slave = master->slaves;
2637  slave < master->slaves + master->slave_count;
2638  slave++) {
2640  }
2641 
2642  if (master->dc_ref_clock) {
2643  uint32_t delay = 0;
2645  }
2646 }
2647 
2648 /*****************************************************************************/
2649 
2653  ec_master_t *master
2654  )
2655 {
2656  // find DC reference clock
2658 
2659  // calculate bus topology
2660  ec_master_calc_topology(master);
2661 
2663 }
2664 
2665 /*****************************************************************************/
2666 
2670  ec_master_t *master
2671  )
2672 {
2673  unsigned int i;
2674  ec_slave_t *slave;
2675 
2676  if (!master->active)
2677  return;
2678 
2679  EC_MASTER_DBG(master, 1, "Requesting OP...\n");
2680 
2681  // request OP for all configured slaves
2682  for (i = 0; i < master->slave_count; i++) {
2683  slave = master->slaves + i;
2684  if (slave->config) {
2686  }
2687  }
2688 
2689 #ifdef EC_REFCLKOP
2690  // always set DC reference clock to OP
2691  if (master->dc_ref_clock) {
2693  }
2694 #endif
2695 }
2696 
2697 /*****************************************************************************/
2698 
2699 int ec_master_dict_upload(ec_master_t *master, uint16_t slave_position)
2700 {
2701  ec_dict_request_t request;
2702  ec_slave_t *slave;
2703  int ret = 0;
2704 
2705  EC_MASTER_DBG(master, 1, "%s(master = 0x%p, slave_position = %u\n",
2706  __func__, master, slave_position);
2707 
2708  ec_dict_request_init(&request);
2709  ec_dict_request_read(&request);
2710 
2711  if (ec_lock_down_interruptible(&master->master_sem)) {
2712  return -EINTR;
2713  }
2714 
2715  if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
2716  ec_lock_up(&master->master_sem);
2717  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
2718  return -EINVAL;
2719  }
2720 
2721  EC_SLAVE_DBG(slave, 1, "Scheduling dictionary upload request.\n");
2722 
2723  // schedule request.
2724  list_add_tail(&request.list, &slave->dict_requests);
2725 
2726  ec_lock_up(&master->master_sem);
2727 
2728  // wait for processing through FSM
2729  if (wait_event_interruptible(master->request_queue,
2730  request.state != EC_INT_REQUEST_QUEUED)) {
2731  // interrupted by signal
2732  ec_lock_down(&master->master_sem);
2733  if (request.state == EC_INT_REQUEST_QUEUED) {
2734  list_del(&request.list);
2735  ec_lock_up(&master->master_sem);
2736  return -EINTR;
2737  }
2738  // request already processing: interrupt not possible.
2739  ec_lock_up(&master->master_sem);
2740  }
2741 
2742  // wait until master FSM has finished processing
2743  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
2744 
2745  if (request.state != EC_INT_REQUEST_SUCCESS) {
2746  ret = -EIO;
2747  }
2748  return ret;
2749 }
2750 
2751 /******************************************************************************
2752  * Application interface
2753  *****************************************************************************/
2754 
2760  ec_master_t *master
2761  )
2762 {
2763  ec_domain_t *domain, *last_domain;
2764  unsigned int index;
2765 
2766  EC_MASTER_DBG(master, 1, "ecrt_master_create_domain(master = 0x%p)\n",
2767  master);
2768 
2769  if (!(domain =
2770  (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) {
2771  EC_MASTER_ERR(master, "Error allocating domain memory!\n");
2772  return ERR_PTR(-ENOMEM);
2773  }
2774 
2775  ec_lock_down(&master->master_sem);
2776 
2777  if (list_empty(&master->domains)) {
2778  index = 0;
2779  } else {
2780  last_domain = list_entry(master->domains.prev, ec_domain_t, list);
2781  index = last_domain->index + 1;
2782  }
2783 
2784  ec_domain_init(domain, master, index);
2785  list_add_tail(&domain->list, &master->domains);
2786 
2787  ec_lock_up(&master->master_sem);
2788 
2789  EC_MASTER_DBG(master, 1, "Created domain %u.\n", domain->index);
2790 
2791  return domain;
2792 }
2793 
2794 /*****************************************************************************/
2795 
2797  ec_master_t *master
2798  )
2799 {
2801  return IS_ERR(d) ? NULL : d;
2802 }
2803 
2804 /*****************************************************************************/
2805 
2807 {
2808  // not currently supported
2809  return -ENOMEM; // FIXME
2810 }
2811 
2812 /*****************************************************************************/
2813 
2815 {
2816  uint32_t domain_offset;
2817  ec_domain_t *domain;
2818  int ret;
2819 #ifdef EC_EOE
2820  int eoe_was_running;
2821 #endif
2822 
2823  EC_MASTER_DBG(master, 1, "ecrt_master_activate(master = 0x%p)\n", master);
2824 
2825  if (master->active) {
2826  EC_MASTER_WARN(master, "%s: Master already active!\n", __func__);
2827  return 0;
2828  }
2829 
2830  ec_lock_down(&master->master_sem);
2831 
2832  // finish all domains
2833  domain_offset = 0;
2834  list_for_each_entry(domain, &master->domains, list) {
2835  ret = ec_domain_finish(domain, domain_offset);
2836  if (ret < 0) {
2837  ec_lock_up(&master->master_sem);
2838  EC_MASTER_ERR(master, "Failed to finish domain 0x%p!\n", domain);
2839  return ret;
2840  }
2841  domain_offset += domain->data_size;
2842  }
2843 
2844  ec_lock_up(&master->master_sem);
2845 
2846  // restart EoE process and master thread with new locking
2847 
2848  ec_master_thread_stop(master);
2849 #ifdef EC_EOE
2850  eoe_was_running = (master->eoe_thread != NULL);
2851  ec_master_eoe_stop(master);
2852 #endif
2853 
2854  EC_MASTER_DBG(master, 1, "FSM datagram is %p.\n", &master->fsm_datagram);
2855 
2856  master->injection_seq_fsm = 0;
2857  master->injection_seq_rt = 0;
2858 
2859  master->send_cb = master->app_send_cb;
2860  master->receive_cb = master->app_receive_cb;
2861  master->cb_data = master->app_cb_data;
2862 
2863 #ifdef EC_EOE
2864  if (eoe_was_running) {
2865  ec_master_eoe_start(master);
2866  }
2867 #endif
2869  "EtherCAT-OP");
2870  if (ret < 0) {
2871  EC_MASTER_ERR(master, "Failed to start master thread!\n");
2872  return ret;
2873  }
2874 
2875  /* Allow scanning after a topology change. */
2876  master->allow_scan = 1;
2877 
2878  master->active = 1;
2879 
2880  // notify state machine, that the configuration shall now be applied
2881  master->config_changed = 1;
2882  master->dc_offset_valid = 0;
2883 
2884  return 0;
2885 }
2886 
2887 /*****************************************************************************/
2888 
2890 {
2891  ec_slave_t *slave;
2892  ec_slave_config_t *sc, *next;
2893 
2894  EC_MASTER_DBG(master, 1, "%s(master = 0x%p)\n", __func__, master);
2895 
2896  if (!master->active) {
2897  EC_MASTER_WARN(master, "%s: Master not active.\n", __func__);
2898  return;
2899  }
2900 
2901 
2902  // clear dc settings on all slaves
2903  list_for_each_entry_safe(sc, next, &master->configs, list) {
2904  if (sc->dc_assign_activate) {
2905  ecrt_slave_config_dc(sc, 0x0000, 0, 0, 0, 0);
2906  }
2907  }
2908 
2909 
2910  for (slave = master->slaves;
2911  slave < master->slaves + master->slave_count;
2912  slave++) {
2913 
2914  // set states for all slaves
2916 
2917  // mark for reconfiguration, because the master could have no
2918  // possibility for a reconfiguration between two sequential operation
2919  // phases.
2920  slave->force_config = 1;
2921  }
2922 }
2923 
2924 /*****************************************************************************/
2925 
2927 {
2928  ec_slave_t *slave;
2929 
2930  EC_MASTER_DBG(master, 1, "%s(master = 0x%p)\n", __func__, master);
2931 
2932  if (!master->active) {
2933  EC_MASTER_WARN(master, "%s: Master not active.\n", __func__);
2934  ec_master_clear_config(master);
2935  return;
2936  }
2937 
2938  ec_master_thread_stop(master);
2939 #ifdef EC_EOE
2940  ec_master_eoe_stop(master);
2941 #endif
2942 
2945  master->cb_data = master;
2946 
2947  ec_master_clear_config(master);
2948 
2949  for (slave = master->slaves;
2950  slave < master->slaves + master->slave_count;
2951  slave++) {
2952 
2953  // set states for all slaves
2955 
2956  // clear read_mbox_busy flag in case slave CoE FSM were interrupted
2957  ec_read_mbox_lock_clear(slave);
2958 
2959  // mark for reconfiguration, because the master could have no
2960  // possibility for a reconfiguration between two sequential operation
2961  // phases.
2962  slave->force_config = 1;
2963  }
2964 
2965  master->app_time = 0ULL;
2966  master->dc_ref_time = 0ULL;
2967  master->dc_offset_valid = 0;
2968 
2969  /* Disallow scanning to get into the same state like after a master
2970  * request (after ec_master_enter_operation_phase() is called). */
2971  master->allow_scan = 0;
2972 
2973  master->active = 0;
2974 
2975 #ifdef EC_EOE
2976  ec_master_eoe_start(master);
2977 #endif
2979  "EtherCAT-IDLE")) {
2980  EC_MASTER_WARN(master, "Failed to restart master thread!\n");
2981  }
2982 }
2983 
2984 /*****************************************************************************/
2985 
2987 {
2988  ec_datagram_t *datagram, *n;
2989  ec_device_index_t dev_idx;
2990  size_t sent_bytes = 0;
2991 
2992 
2993  if (master->injection_seq_rt != master->injection_seq_fsm) {
2994  // inject datagram produced by master FSM
2995  ec_master_queue_datagram(master, &master->fsm_datagram);
2996  master->injection_seq_rt = master->injection_seq_fsm;
2997  }
2998 
3000 
3001  for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
3002  dev_idx++) {
3003  if (unlikely(!master->devices[dev_idx].link_state)) {
3004  // link is down, no datagram can be sent
3005  list_for_each_entry_safe(datagram, n,
3006  &master->datagram_queue, queue) {
3007  if (datagram->device_index == dev_idx) {
3008  datagram->state = EC_DATAGRAM_ERROR;
3009  list_del_init(&datagram->queue);
3010  }
3011  }
3012 
3013  if (!master->devices[dev_idx].dev) {
3014  continue;
3015  }
3016 
3017  // query link state
3018  ec_device_poll(&master->devices[dev_idx]);
3019 
3020  // clear frame statistics
3021  ec_device_clear_stats(&master->devices[dev_idx]);
3022  continue;
3023  }
3024 
3025  // send frames
3026  sent_bytes = max(sent_bytes,
3027  ec_master_send_datagrams(master, dev_idx));
3028  }
3029 
3030  return sent_bytes;
3031 }
3032 
3033 /*****************************************************************************/
3034 
3036 {
3037  unsigned int dev_idx;
3038  ec_datagram_t *datagram, *next;
3039 
3040  // receive datagrams
3041  for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
3042  dev_idx++) {
3043  ec_device_poll(&master->devices[dev_idx]);
3044  }
3046 
3047  // dequeue all datagrams that timed out
3048  list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
3049  if (datagram->state != EC_DATAGRAM_SENT) continue;
3050 
3051 #ifdef EC_HAVE_CYCLES
3052  if (master->devices[EC_DEVICE_MAIN].cycles_poll -
3053  datagram->cycles_sent > timeout_cycles) {
3054 #else
3055  if (master->devices[EC_DEVICE_MAIN].jiffies_poll -
3056  datagram->jiffies_sent > timeout_jiffies) {
3057 #endif
3058  list_del_init(&datagram->queue);
3059  datagram->state = EC_DATAGRAM_TIMED_OUT;
3060  master->stats.timeouts++;
3061 
3062 #ifdef EC_RT_SYSLOG
3063  ec_master_output_stats(master);
3064 
3065  if (unlikely(master->debug_level > 0)) {
3066  unsigned int time_us;
3067 #ifdef EC_HAVE_CYCLES
3068  time_us = (unsigned int)
3069  (master->devices[EC_DEVICE_MAIN].cycles_poll -
3070  datagram->cycles_sent) * 1000 / cpu_khz;
3071 #else
3072  time_us = (unsigned int)
3073  ((master->devices[EC_DEVICE_MAIN].jiffies_poll -
3074  datagram->jiffies_sent) * 1000000 / HZ);
3075 #endif
3076  EC_MASTER_DBG(master, 0, "TIMED OUT datagram %p,"
3077  " index %02X waited %u us.\n",
3078  datagram, datagram->index, time_us);
3079  }
3080 #endif /* RT_SYSLOG */
3081  }
3082  }
3083 }
3084 
3085 /*****************************************************************************/
3086 
3088 {
3089  ec_datagram_t *datagram, *next;
3090 
3091  ec_lock_down(&master->ext_queue_sem);
3092 
3093  list_for_each_entry_safe(datagram, next, &master->ext_datagram_queue,
3094  queue) {
3095  list_del(&datagram->queue);
3096  ec_master_queue_datagram(master, datagram);
3097  }
3098  ec_lock_up(&master->ext_queue_sem);
3099 
3100  return ecrt_master_send(master);
3101 }
3102 
3103 /*****************************************************************************/
3104 
3108  uint16_t alias, uint16_t position, uint32_t vendor_id,
3109  uint32_t product_code)
3110 {
3111  ec_slave_config_t *sc;
3112  unsigned int found = 0;
3113 
3114 
3115  EC_MASTER_DBG(master, 1, "ecrt_master_slave_config(master = 0x%p,"
3116  " alias = %u, position = %u, vendor_id = 0x%08x,"
3117  " product_code = 0x%08x)\n",
3118  master, alias, position, vendor_id, product_code);
3119 
3120  list_for_each_entry(sc, &master->configs, list) {
3121  if (sc->alias == alias && sc->position == position) {
3122  found = 1;
3123  break;
3124  }
3125  }
3126 
3127  if (found) { // config with same alias/position already existing
3128  if (sc->vendor_id != vendor_id || sc->product_code != product_code) {
3129  EC_MASTER_ERR(master, "Slave type mismatch. Slave was"
3130  " configured as 0x%08X/0x%08X before. Now configuring"
3131  " with 0x%08X/0x%08X.\n", sc->vendor_id, sc->product_code,
3132  vendor_id, product_code);
3133  return ERR_PTR(-ENOENT);
3134  }
3135  } else {
3136  EC_MASTER_DBG(master, 1, "Creating slave configuration for %u:%u,"
3137  " 0x%08X/0x%08X.\n",
3138  alias, position, vendor_id, product_code);
3139 
3140  if (!(sc = (ec_slave_config_t *) kmalloc(sizeof(ec_slave_config_t),
3141  GFP_KERNEL))) {
3142  EC_MASTER_ERR(master, "Failed to allocate memory"
3143  " for slave configuration.\n");
3144  return ERR_PTR(-ENOMEM);
3145  }
3146 
3147  ec_slave_config_init(sc, master,
3148  alias, position, vendor_id, product_code);
3149 
3150  ec_lock_down(&master->master_sem);
3151 
3152  // try to find the addressed slave
3155  list_add_tail(&sc->list, &master->configs);
3156 
3157  ec_lock_up(&master->master_sem);
3158  }
3159 
3160  return sc;
3161 }
3162 
3163 /*****************************************************************************/
3164 
3166  uint16_t alias, uint16_t position, uint32_t vendor_id,
3167  uint32_t product_code)
3168 {
3169  ec_slave_config_t *sc = ecrt_master_slave_config_err(master, alias,
3170  position, vendor_id, product_code);
3171  return IS_ERR(sc) ? NULL : sc;
3172 }
3173 
3174 /*****************************************************************************/
3175 
3177  ec_slave_config_t *sc)
3178 {
3179  master->dc_ref_config = sc;
3180 
3181  if (master->dc_ref_config) {
3182  EC_MASTER_INFO(master, "Application selected DC reference clock"
3183  " config (%u-%u) set by application.\n",
3184  master->dc_ref_config->alias,
3185  master->dc_ref_config->position);
3186  }
3187  else {
3188  EC_MASTER_INFO(master, "Application selected DC reference clock"
3189  " config cleared by application.\n");
3190  }
3191 
3192  // update dc datagrams
3194 
3195  return 0;
3196 }
3197 
3198 /*****************************************************************************/
3199 
3200 int ecrt_master(ec_master_t *master, ec_master_info_t *master_info)
3201 {
3202  EC_MASTER_DBG(master, 1, "ecrt_master(master = 0x%p,"
3203  " master_info = 0x%p)\n", master, master_info);
3204 
3205  master_info->slave_count = master->slave_count;
3206  master_info->link_up = master->devices[EC_DEVICE_MAIN].link_state;
3207  master_info->scan_busy = master->scan_busy;
3208  master_info->app_time = master->app_time;
3209  return 0;
3210 }
3211 
3212 /*****************************************************************************/
3213 
3214 int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position,
3215  ec_slave_info_t *slave_info)
3216 {
3217  const ec_slave_t *slave;
3218  unsigned int i;
3219  int ret = 0;
3220 
3221  if (ec_lock_down_interruptible(&master->master_sem)) {
3222  return -EINTR;
3223  }
3224 
3225  slave = ec_master_find_slave_const(master, 0, slave_position);
3226 
3227  if (slave == NULL) {
3228  ret = -ENOENT;
3229  goto out_get_slave;
3230  }
3231 
3232  if (slave->sii_image == NULL) {
3233  EC_MASTER_WARN(master, "Cannot access SII data from slave position %s-%u",
3234  ec_device_names[slave->device_index!=0], slave->ring_position);
3235  ret = -ENOENT;
3236  goto out_get_slave;
3237  }
3238 
3239  slave_info->position = slave->ring_position;
3240  slave_info->vendor_id = slave->sii_image->sii.vendor_id;
3241  slave_info->product_code = slave->sii_image->sii.product_code;
3242  slave_info->revision_number = slave->sii_image->sii.revision_number;
3243  slave_info->serial_number = slave->sii_image->sii.serial_number;
3244  slave_info->alias = slave->effective_alias;
3245  slave_info->current_on_ebus = slave->sii_image->sii.current_on_ebus;
3246 
3247  for (i = 0; i < EC_MAX_PORTS; i++) {
3248  slave_info->ports[i].desc = slave->ports[i].desc;
3249  slave_info->ports[i].link.link_up = slave->ports[i].link.link_up;
3250  slave_info->ports[i].link.loop_closed =
3251  slave->ports[i].link.loop_closed;
3252  slave_info->ports[i].link.signal_detected =
3253  slave->ports[i].link.signal_detected;
3254  slave_info->ports[i].receive_time = slave->ports[i].receive_time;
3255  if (slave->ports[i].next_slave) {
3256  slave_info->ports[i].next_slave =
3257  slave->ports[i].next_slave->ring_position;
3258  } else {
3259  slave_info->ports[i].next_slave = 0xffff;
3260  }
3261  slave_info->ports[i].delay_to_next_dc =
3262  slave->ports[i].delay_to_next_dc;
3263  }
3264  slave_info->upstream_port = slave->upstream_port;
3265 
3266  slave_info->al_state = slave->current_state;
3267  slave_info->error_flag = slave->error_flag;
3268  slave_info->scan_required = slave->scan_required;
3269  slave_info->ready = ec_fsm_slave_is_ready(&slave->fsm);
3270  slave_info->sync_count = slave->sii_image->sii.sync_count;
3271  slave_info->sdo_count = ec_slave_sdo_count(slave);
3272  if (slave->sii_image->sii.name) {
3273  strncpy(slave_info->name, slave->sii_image->sii.name, EC_MAX_STRING_LENGTH);
3274  } else {
3275  slave_info->name[0] = 0;
3276  }
3277 
3278 out_get_slave:
3279  ec_lock_up(&master->master_sem);
3280 
3281  return ret;
3282 }
3283 
3284 /*****************************************************************************/
3285 
3287  void (*send_cb)(void *), void (*receive_cb)(void *), void *cb_data)
3288 {
3289  EC_MASTER_DBG(master, 1, "ecrt_master_callbacks(master = 0x%p,"
3290  " send_cb = 0x%p, receive_cb = 0x%p, cb_data = 0x%p)\n",
3291  master, send_cb, receive_cb, cb_data);
3292 
3293  master->app_send_cb = send_cb;
3294  master->app_receive_cb = receive_cb;
3295  master->app_cb_data = cb_data;
3296 }
3297 
3298 /*****************************************************************************/
3299 
3301 {
3302  ec_device_index_t dev_idx;
3303 
3304  state->slaves_responding = 0U;
3305  state->al_states = 0;
3306  state->link_up = 0U;
3307  state->scan_busy = master->scan_busy ? 1U : 0U;
3308 
3309  for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
3310  dev_idx++) {
3311  /* Announce sum of responding slaves on all links. */
3312  state->slaves_responding += master->fsm.slaves_responding[dev_idx];
3313 
3314  /* Binary-or slave states of all links. */
3315  state->al_states |= master->fsm.slave_states[dev_idx];
3316 
3317  /* Signal link up if at least one device has link. */
3318  state->link_up |= master->devices[dev_idx].link_state;
3319  }
3320 }
3321 
3322 /*****************************************************************************/
3323 
3324 int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx,
3325  ec_master_link_state_t *state)
3326 {
3327  if (dev_idx >= ec_master_num_devices(master)) {
3328  return -EINVAL;
3329  }
3330 
3331  state->slaves_responding = master->fsm.slaves_responding[dev_idx];
3332  state->al_states = master->fsm.slave_states[dev_idx];
3333  state->link_up = master->devices[dev_idx].link_state;
3334 
3335  return 0;
3336 }
3337 
3338 /*****************************************************************************/
3339 
3340 void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
3341 {
3342  master->app_time = app_time;
3343 
3344  if (unlikely(!master->dc_ref_time)) {
3345  master->dc_ref_time = app_time;
3346  }
3347 }
3348 
3349 /*****************************************************************************/
3350 
3351 int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time)
3352 {
3353  if (!master->dc_ref_clock) {
3354  return -ENXIO;
3355  }
3356 
3357  if (master->sync_datagram.state != EC_DATAGRAM_RECEIVED) {
3358  return -EIO;
3359  }
3360 
3361  if (!master->dc_offset_valid) {
3362  return -EAGAIN;
3363  }
3364 
3365  // Get returned datagram time, transmission delay removed.
3366  *time = EC_READ_U32(master->sync_datagram.data) -
3368 
3369  return 0;
3370 }
3371 
3372 /*****************************************************************************/
3373 
3375 {
3376  if (master->dc_ref_clock && master->dc_offset_valid) {
3377  EC_WRITE_U32(master->ref_sync_datagram.data, master->app_time);
3378  ec_master_queue_datagram(master, &master->ref_sync_datagram);
3379  }
3380 }
3381 
3382 /*****************************************************************************/
3383 
3385  ec_master_t *master,
3386  uint64_t sync_time
3387  )
3388 {
3389  if (master->dc_ref_clock) {
3390  EC_WRITE_U32(master->ref_sync_datagram.data, sync_time);
3391  ec_master_queue_datagram(master, &master->ref_sync_datagram);
3392  }
3393 }
3394 
3395 /*****************************************************************************/
3396 
3398 {
3399  if (master->dc_ref_clock && master->dc_offset_valid) {
3400  ec_datagram_zero(&master->sync_datagram);
3401  ec_master_queue_datagram(master, &master->sync_datagram);
3402  }
3403 }
3404 
3405 /*****************************************************************************/
3406 
3408 {
3409  if (master->dc_ref_clock && master->dc_offset_valid) {
3411  ec_master_queue_datagram(master, &master->sync64_datagram);
3412  }
3413 }
3414 
3415 /*****************************************************************************/
3416 
3418 {
3419  if (!master->dc_ref_clock) {
3420  return -ENXIO;
3421  }
3422 
3423  if (master->sync64_datagram.state != EC_DATAGRAM_RECEIVED) {
3424  return -EIO;
3425  }
3426 
3427  if (!master->dc_offset_valid) {
3428  return -EAGAIN;
3429  }
3430 
3431  // Get returned datagram time, transmission delay removed.
3432  *time = EC_READ_U64(master->sync64_datagram.data) -
3434 
3435  return 0;
3436 }
3437 
3438 /*****************************************************************************/
3439 
3441 {
3443  ec_master_queue_datagram(master, &master->sync_mon_datagram);
3444 }
3445 
3446 /*****************************************************************************/
3447 
3449 {
3450  if (master->sync_mon_datagram.state == EC_DATAGRAM_RECEIVED) {
3451  return EC_READ_U32(master->sync_mon_datagram.data) & 0x7fffffff;
3452  } else {
3453  return 0xffffffff;
3454  }
3455 }
3456 
3457 /*****************************************************************************/
3458 
3459 int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
3460  uint16_t index, uint8_t subindex, const uint8_t *data,
3461  size_t data_size, uint32_t *abort_code)
3462 {
3463  ec_sdo_request_t request;
3464  ec_slave_t *slave;
3465  int ret;
3466 
3467  EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
3468  " slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
3469  " data = 0x%p, data_size = %zu, abort_code = 0x%p)\n",
3470  __func__, master, slave_position, index, subindex,
3471  data, data_size, abort_code);
3472 
3473  if (!data_size) {
3474  EC_MASTER_ERR(master, "Zero data size!\n");
3475  return -EINVAL;
3476  }
3477 
3478  ec_sdo_request_init(&request);
3479  ecrt_sdo_request_index(&request, index, subindex);
3480  ret = ec_sdo_request_alloc(&request, data_size);
3481  if (ret) {
3482  ec_sdo_request_clear(&request);
3483  return ret;
3484  }
3485 
3486  memcpy(request.data, data, data_size);
3487  request.data_size = data_size;
3488  ecrt_sdo_request_write(&request);
3489 
3490  if (ec_lock_down_interruptible(&master->master_sem)) {
3491  ec_sdo_request_clear(&request);
3492  return -EINTR;
3493  }
3494 
3495  if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
3496  ec_lock_up(&master->master_sem);
3497  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
3498  ec_sdo_request_clear(&request);
3499  return -EINVAL;
3500  }
3501 
3502  EC_SLAVE_DBG(slave, 1, "Scheduling SDO download request.\n");
3503 
3504  // schedule request.
3505  list_add_tail(&request.list, &slave->sdo_requests);
3506 
3507  ec_lock_up(&master->master_sem);
3508 
3509  // wait for processing through FSM
3510  if (wait_event_interruptible(master->request_queue,
3511  request.state != EC_INT_REQUEST_QUEUED)) {
3512  // interrupted by signal
3513  ec_lock_down(&master->master_sem);
3514  if (request.state == EC_INT_REQUEST_QUEUED) {
3515  list_del(&request.list);
3516  ec_lock_up(&master->master_sem);
3517  ec_sdo_request_clear(&request);
3518  return -EINTR;
3519  }
3520  // request already processing: interrupt not possible.
3521  ec_lock_up(&master->master_sem);
3522  }
3523 
3524  // wait until master FSM has finished processing
3525  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3526 
3527  *abort_code = request.abort_code;
3528 
3529  if (request.state == EC_INT_REQUEST_SUCCESS) {
3530  ret = 0;
3531  } else if (request.errno) {
3532  ret = -request.errno;
3533  } else {
3534  ret = -EIO;
3535  }
3536 
3537  ec_sdo_request_clear(&request);
3538  return ret;
3539 }
3540 
3541 /*****************************************************************************/
3542 
3544  uint16_t slave_position, uint16_t index, const uint8_t *data,
3545  size_t data_size, uint32_t *abort_code)
3546 {
3547  ec_sdo_request_t request;
3548  ec_slave_t *slave;
3549  int ret;
3550 
3551  EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
3552  " slave_position = %u, index = 0x%04X,"
3553  " data = 0x%p, data_size = %zu, abort_code = 0x%p)\n",
3554  __func__, master, slave_position, index, data, data_size,
3555  abort_code);
3556 
3557  if (!data_size) {
3558  EC_MASTER_ERR(master, "Zero data size!\n");
3559  return -EINVAL;
3560  }
3561 
3562  ec_sdo_request_init(&request);
3563  ecrt_sdo_request_index_complete(&request, index);
3564  ret = ec_sdo_request_alloc(&request, data_size);
3565  if (ret) {
3566  ec_sdo_request_clear(&request);
3567  return ret;
3568  }
3569 
3570  memcpy(request.data, data, data_size);
3571  request.data_size = data_size;
3572  ecrt_sdo_request_write(&request);
3573 
3574  if (ec_lock_down_interruptible(&master->master_sem)) {
3575  ec_sdo_request_clear(&request);
3576  return -EINTR;
3577  }
3578 
3579  if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
3580  ec_lock_up(&master->master_sem);
3581  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
3582  ec_sdo_request_clear(&request);
3583  return -EINVAL;
3584  }
3585 
3586  EC_SLAVE_DBG(slave, 1, "Scheduling SDO download request"
3587  " (complete access).\n");
3588 
3589  // schedule request.
3590  list_add_tail(&request.list, &slave->sdo_requests);
3591 
3592  ec_lock_up(&master->master_sem);
3593 
3594  // wait for processing through FSM
3595  if (wait_event_interruptible(master->request_queue,
3596  request.state != EC_INT_REQUEST_QUEUED)) {
3597  // interrupted by signal
3598  ec_lock_down(&master->master_sem);
3599  if (request.state == EC_INT_REQUEST_QUEUED) {
3600  list_del(&request.list);
3601  ec_lock_up(&master->master_sem);
3602  ec_sdo_request_clear(&request);
3603  return -EINTR;
3604  }
3605  // request already processing: interrupt not possible.
3606  ec_lock_up(&master->master_sem);
3607  }
3608 
3609  // wait until master FSM has finished processing
3610  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3611 
3612  *abort_code = request.abort_code;
3613 
3614  if (request.state == EC_INT_REQUEST_SUCCESS) {
3615  ret = 0;
3616  } else if (request.errno) {
3617  ret = -request.errno;
3618  } else {
3619  ret = -EIO;
3620  }
3621 
3622  ec_sdo_request_clear(&request);
3623  return ret;
3624 }
3625 
3626 /*****************************************************************************/
3627 
3628 int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
3629  uint16_t index, uint8_t subindex, uint8_t *target,
3630  size_t target_size, size_t *result_size, uint32_t *abort_code)
3631 {
3632  ec_sdo_request_t request;
3633  ec_slave_t *slave;
3634  int ret = 0;
3635 
3636  EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
3637  " slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
3638  " target = 0x%p, target_size = %zu, result_size = 0x%p,"
3639  " abort_code = 0x%p)\n",
3640  __func__, master, slave_position, index, subindex,
3641  target, target_size, result_size, abort_code);
3642 
3643  ec_sdo_request_init(&request);
3644  ecrt_sdo_request_index(&request, index, subindex);
3645  ecrt_sdo_request_read(&request);
3646 
3647  if (ec_lock_down_interruptible(&master->master_sem)) {
3648  ec_sdo_request_clear(&request);
3649  return -EINTR;
3650  }
3651 
3652  if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
3653  ec_lock_up(&master->master_sem);
3654  ec_sdo_request_clear(&request);
3655  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
3656  return -EINVAL;
3657  }
3658 
3659  EC_SLAVE_DBG(slave, 1, "Scheduling SDO upload request.\n");
3660 
3661  // schedule request.
3662  list_add_tail(&request.list, &slave->sdo_requests);
3663 
3664  ec_lock_up(&master->master_sem);
3665 
3666  // wait for processing through FSM
3667  if (wait_event_interruptible(master->request_queue,
3668  request.state != EC_INT_REQUEST_QUEUED)) {
3669  // interrupted by signal
3670  ec_lock_down(&master->master_sem);
3671  if (request.state == EC_INT_REQUEST_QUEUED) {
3672  list_del(&request.list);
3673  ec_lock_up(&master->master_sem);
3674  ec_sdo_request_clear(&request);
3675  return -EINTR;
3676  }
3677  // request already processing: interrupt not possible.
3678  ec_lock_up(&master->master_sem);
3679  }
3680 
3681  // wait until master FSM has finished processing
3682  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3683 
3684  *abort_code = request.abort_code;
3685 
3686  if (request.state != EC_INT_REQUEST_SUCCESS) {
3687  *result_size = 0;
3688  if (request.errno) {
3689  ret = -request.errno;
3690  } else {
3691  ret = -EIO;
3692  }
3693  } else {
3694  if (request.data_size > target_size) {
3695  EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
3696  ret = -EOVERFLOW;
3697  }
3698  else {
3699  memcpy(target, request.data, request.data_size);
3700  *result_size = request.data_size;
3701  ret = 0;
3702  }
3703  }
3704 
3705  ec_sdo_request_clear(&request);
3706  return ret;
3707 }
3708 
3709 /*****************************************************************************/
3710 
3711 int ecrt_master_sdo_upload_complete(ec_master_t *master, uint16_t slave_position,
3712  uint16_t index, uint8_t *target,
3713  size_t target_size, size_t *result_size, uint32_t *abort_code)
3714 {
3715  ec_sdo_request_t request;
3716  ec_slave_t *slave;
3717  int ret = 0;
3718 
3719  EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
3720  " slave_position = %u, index = 0x%04X,"
3721  " target = 0x%p, target_size = %zu, result_size = 0x%p,"
3722  " abort_code = 0x%p)\n",
3723  __func__, master, slave_position, index,
3724  target, target_size, result_size, abort_code);
3725 
3726  ec_sdo_request_init(&request);
3727  ecrt_sdo_request_index_complete(&request, index);
3728  ecrt_sdo_request_read(&request);
3729 
3730  if (ec_lock_down_interruptible(&master->master_sem)) {
3731  ec_sdo_request_clear(&request);
3732  return -EINTR;
3733  }
3734 
3735  if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
3736  ec_lock_up(&master->master_sem);
3737  ec_sdo_request_clear(&request);
3738  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
3739  return -EINVAL;
3740  }
3741 
3742  EC_SLAVE_DBG(slave, 1, "Scheduling SDO upload request (complete access).\n");
3743 
3744  // schedule request.
3745  list_add_tail(&request.list, &slave->sdo_requests);
3746 
3747  ec_lock_up(&master->master_sem);
3748 
3749  // wait for processing through FSM
3750  if (wait_event_interruptible(master->request_queue,
3751  request.state != EC_INT_REQUEST_QUEUED)) {
3752  // interrupted by signal
3753  ec_lock_down(&master->master_sem);
3754  if (request.state == EC_INT_REQUEST_QUEUED) {
3755  list_del(&request.list);
3756  ec_lock_up(&master->master_sem);
3757  ec_sdo_request_clear(&request);
3758  return -EINTR;
3759  }
3760  // request already processing: interrupt not possible.
3761  ec_lock_up(&master->master_sem);
3762  }
3763 
3764  // wait until master FSM has finished processing
3765  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3766 
3767  *abort_code = request.abort_code;
3768 
3769  if (request.state != EC_INT_REQUEST_SUCCESS) {
3770  *result_size = 0;
3771  if (request.errno) {
3772  ret = -request.errno;
3773  } else {
3774  ret = -EIO;
3775  }
3776  } else {
3777  if (request.data_size > target_size) {
3778  EC_MASTER_ERR(master, "Buffer too small.\n");
3779  ret = -EOVERFLOW;
3780  }
3781  else {
3782  memcpy(target, request.data, request.data_size);
3783  *result_size = request.data_size;
3784  ret = 0;
3785  }
3786  }
3787 
3788  ec_sdo_request_clear(&request);
3789  return ret;
3790 }
3791 
3792 /*****************************************************************************/
3793 
3794 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
3795  uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
3796  uint16_t *error_code)
3797 {
3798  ec_soe_request_t request;
3799  ec_slave_t *slave;
3800  int ret;
3801 
3802  if (drive_no > 7) {
3803  EC_MASTER_ERR(master, "Invalid drive number!\n");
3804  return -EINVAL;
3805  }
3806 
3807  ec_soe_request_init(&request);
3808  ec_soe_request_set_drive_no(&request, drive_no);
3809  ec_soe_request_set_idn(&request, idn);
3810 
3811  ret = ec_soe_request_alloc(&request, data_size);
3812  if (ret) {
3813  ec_soe_request_clear(&request);
3814  return ret;
3815  }
3816 
3817  memcpy(request.data, data, data_size);
3818  request.data_size = data_size;
3819  ec_soe_request_write(&request);
3820 
3821  if (ec_lock_down_interruptible(&master->master_sem)) {
3822  ec_soe_request_clear(&request);
3823  return -EINTR;
3824  }
3825 
3826  if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
3827  ec_lock_up(&master->master_sem);
3828  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
3829  slave_position);
3830  ec_soe_request_clear(&request);
3831  return -EINVAL;
3832  }
3833 
3834  EC_SLAVE_DBG(slave, 1, "Scheduling SoE write request.\n");
3835 
3836  // schedule SoE write request.
3837  list_add_tail(&request.list, &slave->soe_requests);
3838 
3839  ec_lock_up(&master->master_sem);
3840 
3841  // wait for processing through FSM
3842  if (wait_event_interruptible(master->request_queue,
3843  request.state != EC_INT_REQUEST_QUEUED)) {
3844  // interrupted by signal
3845  ec_lock_down(&master->master_sem);
3846  if (request.state == EC_INT_REQUEST_QUEUED) {
3847  // abort request
3848  list_del(&request.list);
3849  ec_lock_up(&master->master_sem);
3850  ec_soe_request_clear(&request);
3851  return -EINTR;
3852  }
3853  ec_lock_up(&master->master_sem);
3854  }
3855 
3856  // wait until master FSM has finished processing
3857  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3858 
3859  if (error_code) {
3860  *error_code = request.error_code;
3861  }
3862  ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
3863  ec_soe_request_clear(&request);
3864 
3865  return ret;
3866 }
3867 
3868 /*****************************************************************************/
3869 
3870 int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position,
3871  uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size,
3872  size_t *result_size, uint16_t *error_code)
3873 {
3874  ec_soe_request_t request;
3875  ec_slave_t *slave;
3876  int ret;
3877 
3878  if (drive_no > 7) {
3879  EC_MASTER_ERR(master, "Invalid drive number!\n");
3880  return -EINVAL;
3881  }
3882 
3883  ec_soe_request_init(&request);
3884  ec_soe_request_set_drive_no(&request, drive_no);
3885  ec_soe_request_set_idn(&request, idn);
3886  ec_soe_request_read(&request);
3887 
3888  if (ec_lock_down_interruptible(&master->master_sem)) {
3889  ec_soe_request_clear(&request);
3890  return -EINTR;
3891  }
3892 
3893  if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
3894  ec_lock_up(&master->master_sem);
3895  ec_soe_request_clear(&request);
3896  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
3897  return -EINVAL;
3898  }
3899 
3900  EC_SLAVE_DBG(slave, 1, "Scheduling SoE read request.\n");
3901 
3902  // schedule request.
3903  list_add_tail(&request.list, &slave->soe_requests);
3904 
3905  ec_lock_up(&master->master_sem);
3906 
3907  // wait for processing through FSM
3908  if (wait_event_interruptible(master->request_queue,
3909  request.state != EC_INT_REQUEST_QUEUED)) {
3910  // interrupted by signal
3911  ec_lock_down(&master->master_sem);
3912  if (request.state == EC_INT_REQUEST_QUEUED) {
3913  list_del(&request.list);
3914  ec_lock_up(&master->master_sem);
3915  ec_soe_request_clear(&request);
3916  return -EINTR;
3917  }
3918  // request already processing: interrupt not possible.
3919  ec_lock_up(&master->master_sem);
3920  }
3921 
3922  // wait until master FSM has finished processing
3923  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3924 
3925  if (error_code) {
3926  *error_code = request.error_code;
3927  }
3928 
3929  if (request.state != EC_INT_REQUEST_SUCCESS) {
3930  if (result_size) {
3931  *result_size = 0;
3932  }
3933  ret = -EIO;
3934  } else { // success
3935  if (request.data_size > target_size) {
3936  EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
3937  ret = -EOVERFLOW;
3938  }
3939  else { // data fits in buffer
3940  if (result_size) {
3941  *result_size = request.data_size;
3942  }
3943  memcpy(target, request.data, request.data_size);
3944  ret = 0;
3945  }
3946  }
3947 
3948  ec_soe_request_clear(&request);
3949  return ret;
3950 }
3951 
3952 /*****************************************************************************/
3953 
3955  unsigned int rt_slave_requests)
3956 {
3957  // set flag as to whether the master or the external application
3958  // should be handling processing the slave request
3959  master->rt_slave_requests = rt_slave_requests;
3960 
3961  if (master->rt_slave_requests) {
3962  EC_MASTER_INFO(master, "Application selected to process"
3963  " slave request by the application.\n");
3964  }
3965  else {
3966  EC_MASTER_INFO(master, "Application selected to process"
3967  " slave request by the master.\n");
3968  }
3969 
3970  return 0;
3971 }
3972 
3973 /*****************************************************************************/
3974 
3976 {
3977  // execute slave state machines
3978  if (ec_lock_down_interruptible(&master->master_sem)) {
3979  return;
3980  }
3981 
3982  // ignore this call if the master is not operational or not set to
3983  // handle the slave requests from the application
3984  if (master->rt_slave_requests && master->rt_slaves_available &&
3985  (master->phase == EC_OPERATION)) {
3986  ec_master_exec_slave_fsms(master);
3987  }
3988 
3989  ec_lock_up(&master->master_sem);
3990 }
3991 
3992 /*****************************************************************************/
3993 
3994 #ifdef EC_EOE
3995 
3996 int ecrt_master_eoe_addif(ec_master_t *master,
3997  uint16_t alias, uint16_t posn)
3998 {
3999  ec_eoe_t *eoe;
4000  char name[EC_DATAGRAM_NAME_SIZE];
4001  int res;
4002 
4003  // check if the name already exists
4004  if (alias) {
4005  snprintf(name, EC_DATAGRAM_NAME_SIZE, "eoe%ua%u", master->index, alias);
4006  } else {
4007  snprintf(name, EC_DATAGRAM_NAME_SIZE, "eoe%us%u", master->index, posn);
4008  }
4009 
4010  ec_lock_down(&master->master_sem);
4011  list_for_each_entry(eoe, &master->eoe_handlers, list) {
4012  if ((eoe->slave == NULL) &&
4013  (strncmp(name, ec_eoe_name(eoe), EC_DATAGRAM_NAME_SIZE) == 0)) {
4014  ec_lock_up(&master->master_sem);
4015  return -EADDRINUSE;
4016  }
4017  }
4018 
4019  // none found, create one
4020  if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
4021  EC_MASTER_ERR(master, "Failed to allocate EoE handler memory!\n");
4022  ec_lock_up(&master->master_sem);
4023  return -EFAULT;
4024  }
4025 
4026  if ((res = ec_eoe_init(master, eoe, alias, posn))) {
4027  EC_MASTER_ERR(master, "Failed to init EoE handler!\n");
4028  kfree(eoe);
4029  ec_lock_up(&master->master_sem);
4030  return res;
4031  }
4032 
4033  list_add_tail(&eoe->list, &master->eoe_handlers);
4034  ec_lock_up(&master->master_sem);
4035 
4036  return 0;
4037 }
4038 
4039 /*****************************************************************************/
4040 
4041 int ecrt_master_eoe_delif(ec_master_t *master,
4042  uint16_t alias, uint16_t posn)
4043 {
4044  ec_eoe_t *eoe;
4045  char name[EC_DATAGRAM_NAME_SIZE];
4046 
4047  if (alias) {
4048  snprintf(name, EC_DATAGRAM_NAME_SIZE, "eoe%ua%u", master->index, alias);
4049  } else {
4050  snprintf(name, EC_DATAGRAM_NAME_SIZE, "eoe%us%u", master->index, posn);
4051  }
4052 
4053  ec_lock_down(&master->master_sem);
4054  list_for_each_entry(eoe, &master->eoe_handlers, list) {
4055  if (strncmp(name, ec_eoe_name(eoe), EC_DATAGRAM_NAME_SIZE) == 0) {
4056  list_del(&eoe->list);
4057  ec_eoe_clear(eoe);
4058  kfree(eoe);
4059  ec_lock_up(&master->master_sem);
4060  return 0;
4061  }
4062  }
4063  ec_lock_up(&master->master_sem);
4064 
4065  return -EFAULT;
4066 }
4067 
4068 #endif
4069 
4070 /*****************************************************************************/
4071 
4072 int ec_master_obj_dict(ec_master_t *master, uint8_t *data,
4073  size_t *data_size, size_t buff_size)
4074 {
4075  uint8_t sdo_req_cmd;
4076  uint8_t sdo_resp_cmd;
4077  uint16_t sdo_index;
4078  uint8_t sdo_sub_index;
4079  uint16_t slave_posn;
4080  ec_slave_t *slave;
4081  char value[32];
4082  size_t value_size;
4083  size_t total_value_size;
4084  int i;
4085  uint8_t link_status;
4086  uint32_t offset;
4087  uint32_t abort_code;
4088  uint8_t resp_error = 0;
4089 
4090 
4091  EC_MASTER_DBG(master, 1, "MBox Gateway request for Master Information.\n");
4092 
4093  // check the mailbox header type is CoE
4094  if ( (*data_size < EC_MBOX_HEADER_SIZE) ||
4095  ((EC_READ_U16(data + 5) & 0x0F) != EC_MBOX_TYPE_COE) ) {
4096  EC_MASTER_ERR(master, "Master does not support requested mailbox type!\n");
4097  return -EPROTONOSUPPORT;
4098  }
4099 
4100  // ensure the CoE Header service is an SDO request
4101  offset = EC_MBOX_HEADER_SIZE;
4102  if ( (*data_size < EC_MBOX_HEADER_SIZE + EC_COE_HEADER_SIZE + 4) ||
4103  (EC_READ_U16(data + offset) >> 12 != 0x2) ) {
4104  EC_MASTER_ERR(master, "Master only supports SDO requests!\n");
4105  return -EINVAL;
4106  }
4107 
4108  // get the SDO cmd, index, subindex
4110  sdo_req_cmd = EC_READ_U8(data + offset) >> 5;
4111  sdo_index = EC_READ_U16(data + offset + 1);
4112  sdo_sub_index = EC_READ_U8(data + offset + 3);
4113 
4114  // get the master lock
4115  if (ec_lock_down_interruptible(&master->master_sem)) {
4116  return -EINTR;
4117  }
4118 
4119  // handle SDO request
4120  // See ETG.5001.3 for required object dictionary entries to support
4121  if ( (sdo_index >= 0x8000) && (sdo_index < 0x8000 + master->slave_count) ) {
4122  // readonly commands
4123  if (sdo_req_cmd != 0x02) {
4124  ec_lock_up(&master->master_sem);
4125  EC_MASTER_ERR(master, "Master, unsupported SDO Command %hhu on"
4126  " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4127  return -EPROTONOSUPPORT;
4128  }
4129 
4130  // calc slave position (slaves start at position 0)
4131  slave_posn = sdo_index - 0x8000;
4132 
4133  // get the slave information
4134  if (!(slave = ec_master_find_slave(master, 0, slave_posn))) {
4135  ec_lock_up(&master->master_sem);
4136  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_posn);
4137  return -EINVAL;
4138  }
4139 
4140  switch (sdo_sub_index) {
4141  case 0 : {
4142  // length of this object (uint8)
4143  // Note: this may need to be 35 (there is a gap between 8 and 33)
4144  value_size = sizeof(uint8_t);
4145  EC_WRITE_U8(value, 35);
4146  } break;
4147  case 1 : {
4148  // slave index (uint16)
4149  // slave posn + MBG slave address offset
4150  value_size = sizeof(uint16_t);
4151  EC_WRITE_U16(value, slave_posn + EC_MBG_SLAVE_ADDR_OFFSET);
4152  } break;
4153  case 2 : {
4154  // slave type (visiblestring[16])
4155  value_size = 16;
4156  memset(value, 0x00, value_size);
4157  if (slave->sii_image) {
4158  snprintf(value, value_size, "%s", slave->sii_image->sii.order);
4159  }
4160  } break;
4161  case 3 : {
4162  // slave name (visiblestring[32])
4163  value_size = 32;
4164  memset(value, 0x00, value_size);
4165  if (slave->sii_image) {
4166  snprintf(value, value_size, "%s", slave->sii_image->sii.name);
4167  }
4168  } break;
4169  case 4 : {
4170  // device type (uint32) (Modular Device Profile)
4171  // need ESI's for this information or a slave that can
4172  // supports mailbox with SDO's (read 0x1000:00)
4173  if (!(slave->sii_image) ||
4174  !(slave->sii_image->sii.mailbox_protocols & EC_MBOX_COE) ||
4175  (ecrt_master_sdo_upload(master, slave_posn, 0x1000, 0x00,
4176  value, sizeof(uint32_t), &value_size, &abort_code) != 0)) {
4177  // return 0 by default
4178  value_size = sizeof(uint32_t);
4179  EC_WRITE_U32(value, 0x00000000);
4180  }
4181  } break;
4182  case 5 : {
4183  // vendor id (uint32)
4184  value_size = sizeof(uint32_t);
4185  EC_WRITE_U32(value, slave->config->vendor_id);
4186  } break;
4187  case 6 : {
4188  // product code (uint32)
4189  value_size = sizeof(uint32_t);
4190  EC_WRITE_U32(value, slave->config->product_code);
4191  } break;
4192  case 7 : {
4193  // revision number (uint32)
4194  value_size = sizeof(uint32_t);
4195  if (slave->sii_image) {
4196  EC_WRITE_U32(value, slave->sii_image->sii.revision_number);
4197  } else {
4198  EC_WRITE_U32(value, 0x00000000);
4199  }
4200  } break;
4201  case 8 : {
4202  // serial number (uint32)
4203  value_size = sizeof(uint32_t);
4204  if (slave->sii_image) {
4205  EC_WRITE_U32(value, slave->sii_image->sii.serial_number);
4206  } else {
4207  EC_WRITE_U32(value, 0x00000000);
4208  }
4209  } break;
4210  case 9 ... 32 : {
4211  // Data can not be read or stored
4212  resp_error = 1;
4213  value_size = sizeof(uint32_t);
4214  EC_WRITE_U32(value, 0x08000020);
4215  } break;
4216  case 33 : {
4217  // mailbox out size (uint16)
4218  value_size = sizeof(uint16_t);
4219  if (slave->sii_image) {
4221  } else {
4222  EC_WRITE_U16(value, 0x0000);
4223  }
4224  } break;
4225  case 34 : {
4226  // mailbox in size (uint16)
4227  value_size = sizeof(uint16_t);
4228  if (slave->sii_image) {
4230  } else {
4231  EC_WRITE_U16(value, 0x0000);
4232  }
4233  } break;
4234  case 35 : {
4235  // link status (uint8), bits 4..7 of register 0x0110:0x0111
4236  link_status = 0;
4237  for (i = 0; i < EC_MAX_PORTS; i++) {
4238  if (slave->ports[i].link.link_up) {
4239  link_status += 1 << (4 + i);
4240  }
4241  }
4242  value_size = sizeof(uint8_t);
4243  EC_WRITE_U8(value, link_status);
4244  } break;
4245  default :
4246  {
4247  // Subindex does not exist error
4248  resp_error = 1;
4249  value_size = sizeof(uint32_t);
4250  EC_WRITE_U32(value, 0x06090011);
4251  } break;
4252  }
4253 
4254  } else if ( (sdo_index >= 0xA000) && (sdo_index < 0xA000 + master->slave_count) ) {
4255  // Note: this is meant to be optional, but the TwinSAFE_Loader.exe seems to
4256  // want to have it
4257 
4258  // calc slave position (slaves start at position 0)
4259  slave_posn = sdo_index - 0xA000;
4260 
4261  switch (sdo_sub_index) {
4262  case 0 : {
4263  // readonly command
4264  if (sdo_req_cmd != 0x02) {
4265  ec_lock_up(&master->master_sem);
4266  EC_MASTER_ERR(master, "Master, unsupported SDO Command %hhu on"
4267  " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4268  return -EPROTONOSUPPORT;
4269  }
4270 
4271  // length of this object (uint8)
4272  value_size = sizeof(uint8_t);
4273  EC_WRITE_U8(value, 2);
4274  } break;
4275  case 1 : {
4276  // AL Status, register 0x130-0x131 (uint16)
4277  // current state
4278 
4279  // readonly command
4280  if (sdo_req_cmd != 0x02) {
4281  ec_lock_up(&master->master_sem);
4282  EC_MASTER_ERR(master, "Master, unsupported SDO Command %hhu on"
4283  " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4284  return -EPROTONOSUPPORT;
4285  }
4286 
4287  // get the slave information
4288  if (!(slave = ec_master_find_slave(master, 0, slave_posn))) {
4289  ec_lock_up(&master->master_sem);
4290  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_posn);
4291  return -EINVAL;
4292  }
4293 
4294  // return the cached slaves current state
4295  // Note: the master only stores the first state byte
4296  // whereas the AL Status register is two bytes
4297  // (second byte reserved)
4298  value_size = sizeof(uint16_t);
4299  EC_WRITE_U16(value, slave->current_state);
4300  } break;
4301  case 2 : {
4302  // AL Control, register 0x120-0x121 (uint16)
4303  // requested state
4304 
4305  // readwrite command
4306  if ( (sdo_req_cmd != 0x02) && (sdo_req_cmd != 0x00) ) {
4307  ec_lock_up(&master->master_sem);
4308  EC_MASTER_ERR(master, "Master, unsupported SDO Command %hhu on"
4309  " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4310  return -EPROTONOSUPPORT;
4311  }
4312 
4313  // get the slave information
4314  if (!(slave = ec_master_find_slave(master, 0, slave_posn))) {
4315  ec_lock_up(&master->master_sem);
4316  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_posn);
4317  return -EINVAL;
4318  }
4319 
4320  if (sdo_req_cmd == 0x02) {
4321  // read
4322  // return the cached slaves requested state
4323  // Note: the master only stores the first state byte
4324  // whereas the AL Control register is two bytes
4325  // (second byte reserved)
4326  value_size = sizeof(uint16_t);
4327  EC_WRITE_U16(value, slave->requested_state);
4328 
4329  } else {
4330  // write (sdo_req_cmd == 0x00)
4331  uint8_t *write_data = data + offset + 4;
4332  size_t write_size;
4333  uint8_t size_specified = EC_READ_U8(data + offset) & 0x01;
4334  if (size_specified) {
4335  write_size = 4 - ((EC_READ_U8(data + offset) & 0x0C) >> 2);
4336  } else {
4337  write_size = 4;
4338  }
4339 
4340  // check write size
4341  if (write_size != 2) {
4342  ec_lock_up(&master->master_sem);
4343  EC_MASTER_ERR(master, "Master, unexpected SDO write data size"
4344  " %zu (expected %u) on 0x%04X:%02X!\n",
4345  write_size, 2, sdo_index, sdo_sub_index);
4346  return -EPROTONOSUPPORT;
4347  }
4348 
4349  // request the slave AL state
4350  ec_slave_request_state(slave, EC_READ_U16(write_data));
4351 
4352  // set blank download response
4353  value_size = sizeof(uint32_t);
4354  memset(value, 0x00, 4);
4355  }
4356  } break;
4357  default : {
4358  // Subindex does not exist error
4359  resp_error = 1;
4360  value_size = sizeof(uint32_t);
4361  EC_WRITE_U32(value, 0x06090011);
4362  } break;
4363  }
4364 
4365  } else if ( (sdo_index >= 0xF020) && (sdo_index < 0xF030) ) {
4366  // readonly commands
4367  if (sdo_req_cmd != 0x02) {
4368  ec_lock_up(&master->master_sem);
4369  EC_MASTER_ERR(master, "Master, unsupported SDO Command %hhu on"
4370  " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4371  return -EPROTONOSUPPORT;
4372  }
4373 
4374  if (sdo_sub_index == 0) {
4375  uint64_t index = master->slave_count;
4376  uint32_t remainder;
4377 
4378  // length of this object (uint8)
4379  value_size = sizeof(uint8_t);
4380 
4381  // calc index and remainder from slave count
4382  remainder = do_div(index, 255);
4383 
4384  if (sdo_index - 0xF020 < index) {
4385  EC_WRITE_U8(value, 255);
4386  } else if ( (sdo_index - 0xF020 == index) && (remainder > 0) ) {
4387  EC_WRITE_U8(value, remainder);
4388  } else {
4389  EC_WRITE_U8(value, 0);
4390  }
4391  } else {
4392  // calc slave position
4393  slave_posn = ((sdo_index - 0xF020) << 8) + sdo_sub_index - (sdo_index - 0xF020 + 1);
4394 
4395  if (slave_posn < master->slave_count) {
4396  // slave index (uint16)
4397  // slave posn + MBG slave address offset
4398  value_size = sizeof(uint16_t);
4399  EC_WRITE_U16(value, slave_posn + EC_MBG_SLAVE_ADDR_OFFSET);
4400  } else {
4401  // Object Not Found error
4402  resp_error = 1;
4403  value_size = sizeof(uint32_t);
4404  EC_WRITE_U32(value, 0x06020000);
4405  }
4406  }
4407 
4408  } else if (sdo_index == 0xF000) {
4409  // readonly commands
4410  if (sdo_req_cmd != 0x02) {
4411  ec_lock_up(&master->master_sem);
4412  EC_MASTER_ERR(master, "Master, unsupported SDO Command %hhu on"
4413  " 0x%04X:%02X!\n", sdo_req_cmd, sdo_index, sdo_sub_index);
4414  return -EPROTONOSUPPORT;
4415  }
4416 
4417  // Modular Device Profile
4418  switch (sdo_sub_index) {
4419  case 0 : {
4420  // length of this object (uint8)
4421  value_size = sizeof(uint8_t);
4422  EC_WRITE_U8(value, 4);
4423  } break;
4424  case 1 : {
4425  // module index distance (uint16)
4426  value_size = sizeof(uint16_t);
4427  EC_WRITE_U16(value, 0x0001);
4428  } break;
4429  case 2 : {
4430  // maximum number of modules (uint16)
4431  // Gateway information limit
4432  value_size = sizeof(uint16_t);
4433  EC_WRITE_U16(value, 4080);
4434  } break;
4435  case 3 : {
4436  // general configuration (uint32)
4437  value_size = sizeof(uint32_t);
4438  EC_WRITE_U32(value, 0x000000FF);
4439  } break;
4440  case 4 : {
4441  // general information (uint32)
4442  value_size = sizeof(uint32_t);
4443  EC_WRITE_U32(value, 0x00000000);
4444  } break;
4445  default : {
4446  // Subindex does not exist error
4447  resp_error = 1;
4448  value_size = sizeof(uint32_t);
4449  EC_WRITE_U32(value, 0x06090011);
4450  } break;
4451  }
4452 
4453  } else {
4454  // Object Not Found error
4455  resp_error = 1;
4456  value_size = sizeof(uint32_t);
4457  EC_WRITE_U32(value, 0x06020000);
4458  }
4459 
4460  ec_lock_up(&master->master_sem);
4461 
4462 
4463  // do we need to allow room for a complete size field?
4464  if ( (value_size > 0) && (value_size <= 4) ) {
4465  total_value_size = value_size;
4466  } else {
4467  total_value_size = value_size + sizeof(uint32_t);
4468  }
4469 
4470  // set reply
4471  if (EC_MBOX_HEADER_SIZE + EC_COE_HEADER_SIZE + 4 + total_value_size > buff_size) {
4472  EC_MASTER_ERR(master, "Buffer too small.\n");
4473  return -EOVERFLOW;
4474  }
4475  else {
4476  // update data_size
4477  *data_size = EC_MBOX_HEADER_SIZE + EC_COE_HEADER_SIZE + 4 + total_value_size;
4478 
4479  // update Mailbox Header Length (length of CoE Header onwards)
4480  EC_WRITE_U16(data, *data_size - EC_MBOX_HEADER_SIZE);
4481 
4482  // update CoE service response or SDO command specifier on error
4483  if (resp_error) {
4484  // not happy, return abort SDO transfer request
4486  EC_WRITE_U8(data + offset, 0x04 << 5);
4487 
4488  // set abort value
4489  memcpy(data + offset + 4, value, value_size);
4490  } else {
4491  // happy, return service code 3 (SDO response)
4492  offset = EC_MBOX_HEADER_SIZE;
4493  EC_WRITE_U16(data + offset, 0x03 << 12);
4494 
4495  // set SDO command specifier
4496  if (sdo_req_cmd == 0x02) {
4497  // upload response
4498  sdo_resp_cmd = 0x02;
4499  } else {
4500  // download response
4501  sdo_resp_cmd = 0x01;
4502  }
4503 
4504  // set value size
4506  if ( (value_size > 0) && (value_size <= 4) ) {
4507  // upload response, expedited size specified
4508  // bit 0 1 = size specified
4509  // bit 1 1 = expedited
4510  // bit 2..3 4 - size
4511  // bit 5..7 command specifier
4512  EC_WRITE_U8(data + offset, (sdo_resp_cmd << 5) +
4513  ((4 - value_size) << 2) + 0x02 + 0x01);
4514 
4515  // set offset to data
4516  offset += 4;
4517  } else {
4518  // upload response, size specified
4519  EC_WRITE_U8(data + offset, (sdo_resp_cmd << 5) + 0x01);
4520 
4521  // set value size
4522  offset += 4;
4523  EC_WRITE_U32(data + offset, value_size);
4524 
4525  // set offset to value
4526  offset += sizeof(uint32_t);
4527  }
4528 
4529  // set value
4530  memcpy(data + offset, value, value_size);
4531  }
4532  }
4533 
4534 
4535  return 0;
4536 }
4537 
4538 /*****************************************************************************/
4539 
4540 int ec_master_mbox_gateway(ec_master_t *master, uint8_t *data,
4541  size_t *data_size, size_t buff_size)
4542 {
4543  ec_mbg_request_t request;
4544  uint16_t slave_posn;
4545  ec_slave_t *slave;
4546  int ret = 0;
4547 
4548  // get the slave address
4549  slave_posn = EC_READ_U16(data + 2);
4550 
4551  // check if slave address is zero (master object dictionary request)
4552  if (slave_posn == 0)
4553  {
4554  // request for master information
4555  ret = ec_master_obj_dict(master, data, data_size, buff_size);
4556  }
4557  else if (slave_posn >= EC_MBG_SLAVE_ADDR_OFFSET)
4558  {
4559  // calculate the slave position address
4560  slave_posn -= EC_MBG_SLAVE_ADDR_OFFSET;
4561 
4562  // pass on request to slave
4563  ec_mbg_request_init(&request);
4564  ret = ec_mbg_request_copy_data(&request, data, *data_size);
4565  *data_size = 0;
4566  if (ret) {
4567  ec_mbg_request_clear(&request);
4568  return ret;
4569  }
4570  ec_mbg_request_run(&request);
4571 
4572  if (ec_lock_down_interruptible(&master->master_sem)) {
4573  ec_mbg_request_clear(&request);
4574  return -EINTR;
4575  }
4576 
4577  // check for a valid slave request
4578  if (!(slave = ec_master_find_slave(master, 0, slave_posn))) {
4579  ec_lock_up(&master->master_sem);
4580  ec_mbg_request_clear(&request);
4581  EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_posn);
4582  return -EINVAL;
4583  }
4584 
4585  EC_SLAVE_DBG(slave, 1, "Scheduling MBox Gateway request.\n");
4586 
4587  // schedule request.
4588  list_add_tail(&request.list, &slave->mbg_requests);
4589 
4590  ec_lock_up(&master->master_sem);
4591 
4592  // wait for processing through FSM
4593  if (wait_event_interruptible(master->request_queue,
4594  request.state != EC_INT_REQUEST_QUEUED)) {
4595  // interrupted by signal
4596  ec_lock_down(&master->master_sem);
4597  if (request.state == EC_INT_REQUEST_QUEUED) {
4598  list_del(&request.list);
4599  ec_lock_up(&master->master_sem);
4600  ec_mbg_request_clear(&request);
4601  return -EINTR;
4602  }
4603  // request already processing: interrupt not possible.
4604  ec_lock_up(&master->master_sem);
4605  }
4606 
4607  // wait until master FSM has finished processing
4608  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4609 
4610  if (request.state != EC_INT_REQUEST_SUCCESS) {
4611  if (request.error_code) {
4612  ret = -request.error_code;
4613  } else {
4614  ret = -EIO;
4615  }
4616  } else {
4617  if (request.data_size > buff_size) {
4618  EC_MASTER_ERR(master, "Buffer too small.\n");
4619  ret = -EOVERFLOW;
4620  }
4621  else {
4622  memcpy(data, request.data, request.data_size);
4623  *data_size = request.data_size;
4624  ret = 0;
4625  }
4626  }
4627 
4628  ec_mbg_request_clear(&request);
4629  } else {
4630  EC_MASTER_ERR(master, "MBox Gateway: Invalid slave offset address %u!\n", slave_posn);
4631  return -EINVAL;
4632  }
4633 
4634 
4635 
4636  return ret;
4637 }
4638 
4639 /*****************************************************************************/
4640 
4642 {
4643  ec_slave_config_t *sc;
4644 
4645  list_for_each_entry(sc, &master->configs, list) {
4646  if (sc->slave) {
4648  }
4649  }
4650 }
4651 
4652 /*****************************************************************************/
4653 
4656 EXPORT_SYMBOL(ecrt_master_create_domain);
4657 EXPORT_SYMBOL(ecrt_master_setup_domain_memory);
4658 EXPORT_SYMBOL(ecrt_master_activate);
4659 EXPORT_SYMBOL(ecrt_master_deactivate_slaves);
4660 EXPORT_SYMBOL(ecrt_master_deactivate);
4661 EXPORT_SYMBOL(ecrt_master_send);
4662 EXPORT_SYMBOL(ecrt_master_send_ext);
4663 EXPORT_SYMBOL(ecrt_master_receive);
4664 EXPORT_SYMBOL(ecrt_master_callbacks);
4665 EXPORT_SYMBOL(ecrt_master);
4666 EXPORT_SYMBOL(ecrt_master_get_slave);
4667 EXPORT_SYMBOL(ecrt_master_slave_config);
4668 EXPORT_SYMBOL(ecrt_master_select_reference_clock);
4669 EXPORT_SYMBOL(ecrt_master_state);
4670 EXPORT_SYMBOL(ecrt_master_link_state);
4671 EXPORT_SYMBOL(ecrt_master_application_time);
4672 EXPORT_SYMBOL(ecrt_master_sync_reference_clock);
4674 EXPORT_SYMBOL(ecrt_master_sync_slave_clocks);
4675 EXPORT_SYMBOL(ecrt_master_reference_clock_time);
4678 EXPORT_SYMBOL(ecrt_master_sync_monitor_queue);
4679 EXPORT_SYMBOL(ecrt_master_sync_monitor_process);
4680 EXPORT_SYMBOL(ecrt_master_sdo_download);
4681 EXPORT_SYMBOL(ecrt_master_sdo_download_complete);
4682 EXPORT_SYMBOL(ecrt_master_sdo_upload);
4683 EXPORT_SYMBOL(ecrt_master_sdo_upload_complete);
4684 EXPORT_SYMBOL(ecrt_master_write_idn);
4685 EXPORT_SYMBOL(ecrt_master_read_idn);
4686 EXPORT_SYMBOL(ecrt_master_rt_slave_requests);
4687 EXPORT_SYMBOL(ecrt_master_exec_slave_requests);
4688 #ifdef EC_EOE
4689 EXPORT_SYMBOL(ecrt_master_eoe_addif);
4690 EXPORT_SYMBOL(ecrt_master_eoe_delif);
4691 #endif
4692 EXPORT_SYMBOL(ecrt_master_reset);
4693 
4696 /*****************************************************************************/
uint8_t * data
Mailbox response data.
Definition: datagram.h:123
ec_lock_t ext_queue_sem
Semaphore protecting the ext_datagram_queue.
Definition: master.h:283
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
struct list_head mbg_requests
EoE set IP parameter requests.
Definition: slave.h:279
unsigned int injection_seq_fsm
Datagram injection sequence number for the FSM side.
Definition: master.h:234
uint32_t serial_number
Serial-Number stored on the slave.
Definition: ecrt.h:385
void ec_master_clear_eoe_handlers(ec_master_t *master, unsigned int free_all)
Clear and free auto created EoE handlers.
Definition: master.c:480
#define EC_IO_TIMEOUT
Datagram timeout in microseconds.
Definition: globals.h:47
ec_slave_port_desc_t desc
Physical port type.
Definition: ecrt.h:389
unsigned int reserved
True, if the master is in use.
Definition: master.h:204
struct list_head ext_datagram_queue
Queue for non-application datagrams.
Definition: master.h:281
int ec_mac_is_zero(const uint8_t *)
Definition: module.c:277
uint16_t ring_position
Ring position.
Definition: slave.h:221
uint32_t revision_number
Revision number.
Definition: slave.h:162
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
Definition: datagram.h:105
uint8_t upstream_port
Index of master-facing port.
Definition: slave.h:232
void ec_master_clear_config(ec_master_t *master)
Clear the configuration applied by the application.
Definition: master.c:664
void ec_slave_calc_upstream_port(ec_slave_t *slave)
Calculates which of ports 0-3 appears to be the upstream one.
Definition: slave.c:1085
#define EC_ADDR_LEN
Size of the EtherCAT address field.
Definition: globals.h:87
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:889
void ecrt_sdo_request_index_complete(ec_sdo_request_t *req, uint16_t index)
Set the SDO index and prepare for complete-access.
Definition: sdo_request.c:195
ec_internal_request_state_t state
Request state.
void ec_soe_request_set_idn(ec_soe_request_t *req, uint16_t idn)
Set IDN.
Definition: soe_request.c:117
int ec_rtdm_dev_init(ec_rtdm_dev_t *rtdm_dev, ec_master_t *master)
Initialize an RTDM device.
Definition: rtdm.c:69
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Definition: globals.h:142
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
Processes the DC synchrony monitoring datagram.
Definition: master.c:3448
size_t data_size
Size of the data in data.
Definition: datagram.h:98
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
void ec_slave_config_init(ec_slave_config_t *sc, ec_master_t *master, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code)
Slave configuration constructor.
Definition: slave_config.c:55
struct list_head list
List item.
Definition: slave.h:202
uint8_t sync_count
Number of sync managers.
Definition: ecrt.h:402
char * ec_eoe_name(const ec_eoe_t *eoe)
Returns the eoe device name.
Definition: ethernet.c:716
void ec_master_calc_dc(ec_master_t *master)
Distributed-clocks calculations.
Definition: master.c:2652
unsigned int fsm_exec_count
Number of entries in execution list.
Definition: master.h:308
u64 last_loss
Tx/Rx difference of last statistics cycle.
Definition: master.h:174
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
uint8_t error_flag
Error flag for that slave.
Definition: ecrt.h:399
void ec_master_clear(ec_master_t *master)
Destructor.
Definition: master.c:422
EtherCAT Mailbox Gateway request.
struct list_head list
List item.
Definition: soe_request.h:49
struct list_head sii_requests
SII write requests.
Definition: master.h:334
void ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
Definition: master.c:3397
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:108
size_t data_size
Size of the process data.
Definition: domain.h:61
ec_mbox_data_t mbox_eoe_init_data
Received mailbox data for EoE, type eoe init reponse.
Definition: slave.h:289
unsigned long jiffies_poll
jiffies of last poll
Definition: device.h:106
unsigned int reboot
Reboot requested.
Definition: master.h:264
ec_slave_t * slave
pointer to the corresponding slave
Definition: ethernet.h:75
size_t data_size
Size of MBox request data.
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
uint64_t app_time_sent
App time, when the datagram was sent.
Definition: datagram.h:106
OP (mailbox communication and input/output update)
Definition: globals.h:170
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: master.h:181
uint16_t configured_tx_mailbox_offset
Configured send mailbox offset.
Definition: slave.h:246
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:58
ec_slave_config_t * ec_master_get_config(const ec_master_t *master, unsigned int pos)
Get a slave configuration via its position in the list.
Definition: master.c:2327
unsigned int slaves_responding[EC_MAX_NUM_DEVICES]
Number of responding slaves for every device.
Definition: fsm_master.h:79
void * pcap_data
pcap debug output memory pointer
Definition: master.h:313
int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx, ec_master_link_state_t *state)
Reads the current state of a redundant link.
Definition: master.c:3324
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:231
void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
Definition: master.c:3340
void ec_fsm_master_reset(ec_fsm_master_t *fsm)
Reset state machine.
Definition: fsm_master.c:116
void ec_master_request_op(ec_master_t *master)
Request OP state for configured slaves.
Definition: master.c:2669
static int ec_master_eoe_thread(void *)
Does the Ethernet over EtherCAT processing.
Definition: master.c:2131
int ec_fsm_slave_is_ready(const ec_fsm_slave_t *fsm)
Returns, if the FSM is currently not busy and ready to execute.
Definition: fsm_slave.c:681
CANopen SDO request.
Definition: sdo_request.h:48
unsigned int slave_count
Number of slaves in the bus.
Definition: ecrt.h:344
ec_slave_state_t current_state
Current application state.
Definition: slave.h:237
void ec_master_leave_operation_phase(ec_master_t *master)
Transition function from OPERATION to IDLE phase.
Definition: master.c:916
#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
Complete slave information interface data image.
Definition: slave.h:201
ec_datagram_t sync_mon_datagram
Datagram used for DC synchronisation monitoring.
Definition: master.h:258
EtherCAT slave structure.
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:63
uint32_t vendor_id
Vendor-ID stored on the slave.
Definition: ecrt.h:382
void ec_device_clear(ec_device_t *device)
Destructor.
Definition: device.c:163
ec_mbox_data_t mbox_mbg_data
Received mailbox data for MBox Gateway.
Definition: slave.h:295
struct list_head list
List item.
Definition: domain.h:56
ec_mbox_data_t mbox_foe_data
Received mailbox data for FoE.
Definition: slave.h:292
struct list_head eoe_handlers
Ethernet over EtherCAT handlers.
Definition: master.h:320
uint32_t product_code
Slave product code.
Definition: slave_config.h:126
ec_slave_port_link_t link
Port link state.
Definition: ecrt.h:390
int ec_master_thread_start(ec_master_t *master, int(*thread_func)(void *), const char *name)
Starts the master thread.
Definition: master.c:709
Operation phase.
Definition: master.h:143
dev_t device_number
Device number for master cdevs.
Definition: module.c:72
ec_slave_port_link_t link
Port link status.
Definition: slave.h:141
unsigned int allow_scan
True, if slave scanning is allowed.
Definition: master.h:266
size_t max_queue_size
Maximum size of datagram queue.
Definition: master.h:294
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:692
uint16_t position
Index after alias.
Definition: slave_config.h:123
unsigned int eoe_count
Number of EOE interfaces.
Definition: module.c:63
static int ec_master_operation_thread(void *)
Master kernel thread function for OPERATION phase.
Definition: master.c:1938
void ec_soe_request_read(ec_soe_request_t *req)
Request a read operation.
Definition: soe_request.c:232
const ec_slave_t * ec_master_find_slave_const(const ec_master_t *master, uint16_t alias, uint16_t position)
Finds a slave in the bus, given the alias and position.
Definition: master.c:2278
#define EC_FRAME_HEADER_SIZE
Size of an EtherCAT frame header.
Definition: globals.h:78
void ecrt_master_callbacks(ec_master_t *master, void(*send_cb)(void *), void(*receive_cb)(void *), void *cb_data)
Sets the locking callbacks.
Definition: master.c:3286
EtherCAT datagram.
Definition: datagram.h:88
struct list_head list
List item.
Definition: slave_config.h:119
uint32_t serial_number
Serial number.
Definition: slave.h:163
int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position, ec_slave_info_t *slave_info)
Obtains slave information.
Definition: master.c:3214
struct list_head fsm_exec_list
Slave FSM execution list.
Definition: master.h:307
void ec_master_expire_slave_config_requests(ec_master_t *master)
Abort active requests for slave configs without attached slaves.
Definition: master.c:2222
char * order
Order number.
Definition: slave.h:182
const ec_domain_t * ec_master_find_domain_const(const ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
Definition: master.c:2406
const ec_eoe_t * ec_master_get_eoe_handler_const(const ec_master_t *master, uint16_t index)
Get an EoE handler via its position in the list.
Definition: master.c:2445
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2642
uint32_t abort_code
SDO request abort code.
Definition: sdo_request.h:68
size_t ecrt_master_send_ext(ec_master_t *master)
Sends non-application datagrams.
Definition: master.c:3087
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:250
ec_slave_state_t slave_states[EC_MAX_NUM_DEVICES]
AL states of responding slaves for every device.
Definition: fsm_master.h:83
struct list_head emerg_reg_requests
Emergency register access requests.
Definition: master.h:335
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:58
#define EC_COE_HEADER_SIZE
CoE header size.
Definition: globals.h:103
char name[EC_DATAGRAM_NAME_SIZE]
Description of the datagram.
Definition: datagram.h:114
uint16_t alias
Slave alias.
Definition: slave_config.h:122
void ec_device_update_stats(ec_device_t *device)
Update device statistics.
Definition: device.c:557
struct list_head domains
List of domains.
Definition: master.h:244
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
Finite state machine of an EtherCAT slave.
Definition: fsm_slave.h:63
ec_datagram_t * datagram
Previous state datagram.
Definition: fsm_slave.h:69
uint32_t delay_to_next_dc
Delay [ns] to next DC slave.
Definition: ecrt.h:395
ec_fsm_slave_t fsm
Slave state machine.
Definition: slave.h:282
#define EC_FIND_CONFIG
Common implementation for ec_master_get_config() and ec_master_get_config_const().
Definition: master.c:2313
uint16_t error_code
SoE error code.
Definition: soe_request.h:61
uint16_t working_counter
Working counter.
Definition: datagram.h:100
ec_domain_t * ecrt_master_create_domain(ec_master_t *master)
Creates a new process data domain.
Definition: master.c:2796
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:52
unsigned long jiffies
Jiffies of last statistic cycle.
Definition: master.h:187
unsigned int rt_slaves_available
if True, slave requests can be handled by calls to ecrt_master_exec_requests() from the applications ...
Definition: master.h:299
int16_t current_on_ebus
Power consumption in mA.
Definition: slave.h:187
ec_slave_t * ec_master_find_slave(ec_master_t *master, uint16_t alias, uint16_t position)
Finds a slave in the bus, given the alias and position.
Definition: master.c:2262
uint8_t link_state
device link state
Definition: device.h:97
int ecrt_master_setup_domain_memory(ec_master_t *master)
setup the domain&#39;s process data memory.
Definition: master.c:2806
static unsigned int debug_level
Debug level parameter.
Definition: module.c:66
u64 last_rx_count
Number of frames received of last statistics cycle.
Definition: master.h:167
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:220
Sent (still in the queue).
Definition: datagram.h:77
unsigned int slaves_responding
Sum of responding slaves on all Ethernet devices.
Definition: ecrt.h:270
void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
Reads the current master state.
Definition: master.c:3300
Configured Address Physical Read.
Definition: datagram.h:55
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:338
void ec_master_clear_device_stats(ec_master_t *)
Clears the common device statistics.
Definition: master.c:1615
void ecrt_master_sync_reference_clock_to(ec_master_t *master, uint64_t sync_time)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:3384
uint16_t station_address
Configured station address.
Definition: slave.h:222
const char * ec_device_names[2]
Device names.
Definition: module.c:472
unsigned int sync_count
Number of sync managers.
Definition: slave.h:191
struct list_head list
List head.
Definition: fsm_master.h:53
SII write request.
Definition: fsm_master.h:52
void ec_slave_clear(ec_slave_t *slave)
Slave destructor.
Definition: slave.c:250
ec_domain_t * ecrt_master_create_domain_err(ec_master_t *master)
Same as ecrt_master_create_domain(), but with ERR_PTR() return value.
Definition: master.c:2759
unsigned int link_up
true, if the network link is up.
Definition: ecrt.h:345
void ec_datagram_output_stats(ec_datagram_t *datagram)
Outputs datagram statistics at most every second.
Definition: datagram.c:644
int ec_master_enter_idle_phase(ec_master_t *master)
Transition function from ORPHANED to IDLE phase.
Definition: master.c:764
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:169
ec_datagram_type_t type
Datagram type (APRD, BWR, etc.).
Definition: datagram.h:93
const ec_slave_config_t * ec_master_get_config_const(const ec_master_t *master, unsigned int pos)
Get a slave configuration via its position in the list.
Definition: master.c:2342
void ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate, uint32_t sync0_cycle_time, int32_t sync0_shift_time, uint32_t sync1_cycle_time, int32_t sync1_shift_time)
Configure distributed clocks.
Definition: slave_config.c:990
struct ec_slave_info_t::@6 ports[EC_MAX_PORTS]
Port information.
Global definitions and macros.
uint32_t revision_number
Revision-Number stored on the slave.
Definition: ecrt.h:384
Logical Write.
Definition: datagram.h:62
EtherCAT master structure.
int ecrt_master_64bit_reference_clock_time(ec_master_t *master, uint64_t *time)
Get the 64bit dc reference slave clock time.
Definition: master.c:3417
void * cb_data
Current callback data.
Definition: master.h:327
SAFEOP (mailbox communication and input update)
Definition: globals.h:168
void ec_pdo_clear(ec_pdo_t *pdo)
PDO destructor.
Definition: pdo.c:94
void ec_device_send(ec_device_t *device, size_t size)
Sends the content of the transmit socket buffer.
Definition: device.c:375
ec_lock_t config_sem
Semaphore protecting the config_busy variable and the allow_config flag.
Definition: master.h:273
uint8_t * data
Pointer to MBox request data.
void ec_fsm_master_init(ec_fsm_master_t *fsm, ec_master_t *master, ec_datagram_t *datagram)
Constructor.
Definition: fsm_master.c:83
Initial state of a new datagram.
Definition: datagram.h:75
int ecrt_master_sdo_upload_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t *target, size_t target_size, size_t *result_size, uint32_t *abort_code)
Executes an SDO upload request to read data from a slave via complete access.
Definition: master.c:3711
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:106
ec_slave_t * fsm_slave
Slave that is queried next for FSM exec.
Definition: master.h:306
unsigned int send_interval
Interval between two calls to ecrt_master_send().
Definition: master.h:292
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:54
EtherCAT slave.
Definition: slave.h:214
void ec_master_clear_sii_images(ec_master_t *master)
Clear the SII data applied during bus scanning.
Definition: master.c:559
uint8_t datagram_index
Current datagram index.
Definition: master.h:279
ec_lock_t device_sem
Device semaphore.
Definition: master.h:226
void ec_master_attach_slave_configs(ec_master_t *master)
Attaches the slave configurations to the slaves.
Definition: master.c:2207
struct list_head datagram_queue
Datagram queue.
Definition: master.h:278
ec_slave_t * slave
slave the FSM runs on
Definition: fsm_slave.h:64
void ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
Definition: sdo_request.c:232
char name[EC_MAX_STRING_LENGTH]
Name of the slave.
Definition: ecrt.h:404
void ec_sdo_request_clear(ec_sdo_request_t *req)
SDO request destructor.
Definition: sdo_request.c:76
struct task_struct * eoe_thread
EoE thread.
Definition: master.h:319
struct list_head sdo_requests
SDO access requests.
Definition: slave.h:274
Master state.
Definition: ecrt.h:269
uint16_t error_code
MBox Gateway error code.
unsigned int unmatched
unmatched datagrams (received, but not queued any longer)
Definition: master.h:154
unsigned int auto_created
auto created flag.
Definition: ethernet.h:84
unsigned int ext_ring_idx_fsm
Index in external datagram ring for FSM side.
Definition: master.h:290
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
Definition: datagram.c:179
#define EC_TX_RING_SIZE
Size of the transmit ring.
Definition: device.h:52
int ec_master_debug_level(ec_master_t *master, unsigned int level)
Set the debug level.
Definition: master.c:2470
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: master.h:175
u8 dc_offset_valid
DC slaves have valid system time offsets.
Definition: master.h:251
uint64_t app_time
Application time.
Definition: ecrt.h:347
ec_sii_image_t * sii_image
Current complete SII image.
Definition: slave.h:267
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: master.h:183
int ec_mbg_request_copy_data(ec_mbg_request_t *req, const uint8_t *source, size_t size)
Copies Mbox Gateway data from an external source.
Ethernet over EtherCAT (EoE)
struct list_head soe_requests
SoE requests.
Definition: slave.h:277
#define EC_DATAGRAM_HEADER_SIZE
Size of an EtherCAT datagram header.
Definition: globals.h:81
#define EC_MBG_SLAVE_ADDR_OFFSET
Mailbox Gateway, Mailbox header slave address offset.
Definition: globals.h:106
ec_datagram_state_t state
State.
Definition: datagram.h:101
char * eoe_interfaces[MAX_EOE]
EOE interfaces parameter.
Definition: module.c:62
CANopen over EtherCAT.
Definition: globals.h:184
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:227
ec_datagram_t fsm_datagram
Datagram used for state machines.
Definition: master.h:230
ec_slave_config_t * config
Current configuration.
Definition: slave.h:235
ec_master_phase_t phase
Master phase.
Definition: master.h:231
#define EC_WRITE_U32(DATA, VAL)
Write a 32-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2676
ec_slave_t * slaves
Array of slaves on the bus.
Definition: master.h:239
void ec_domain_clear(ec_domain_t *domain)
Domain destructor.
Definition: domain.c:97
void ec_soe_request_set_drive_no(ec_soe_request_t *req, uint8_t drive_no)
Set drive number.
Definition: soe_request.c:105
void ec_slave_calc_port_delays(ec_slave_t *slave)
Calculates the port transmission delays.
Definition: slave.c:1184
int ec_domain_finish(ec_domain_t *domain, uint32_t base_address)
Finishes a domain.
Definition: domain.c:308
static unsigned long ext_injection_timeout_jiffies
Timeout for external datagram injection [jiffies].
Definition: master.c:97
int ec_eoe_is_idle(const ec_eoe_t *eoe)
Returns the idle state.
Definition: ethernet.c:705
PDO description.
Definition: pdo.h:49
EtherCAT device.
Definition: device.h:90
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:172
ec_domain_t * ec_master_find_domain(ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
Definition: master.c:2391
size_t data_size
Size of SDO data.
Definition: soe_request.h:55
ec_datagram_t sync64_datagram
Datagram used to retrieve 64bit ref slave system clock time.
Definition: master.h:256
unsigned int timeouts
datagram timeouts
Definition: master.h:152
unsigned int debug_level
Master debug level.
Definition: master.h:310
int ec_datagram_frmw(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FRMW datagram.
Definition: datagram.c:370
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:77
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:2357
Orphaned phase.
Definition: master.h:139
struct list_head list
List item.
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
Definition: master.h:185
unsigned int corrupted
corrupted frames
Definition: master.h:153
u64 last_tx_count
Number of frames sent of last statistics cycle.
Definition: master.h:165
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:262
int ecrt_master_select_reference_clock(ec_master_t *master, ec_slave_config_t *sc)
Selects the reference clock for distributed clocks.
Definition: master.c:3176
void ec_master_exec_slave_fsms(ec_master_t *master)
Execute slave FSMs.
Definition: master.c:1774
void ec_soe_request_clear(ec_soe_request_t *req)
SoE request destructor.
Definition: soe_request.c:77
unsigned int ext_ring_idx_rt
Index in external datagram ring for RT side.
Definition: master.h:288
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:240
unsigned int scan_busy
Current scan state.
Definition: master.h:265
ec_device_index_t
Master devices.
Definition: globals.h:236
void(* receive_cb)(void *)
Current receive datagrams callback.
Definition: master.h:326
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:142
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:178
uint16_t alias
Configured station alias.
Definition: slave.h:159
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
Definition: ecrt.h:2659
unsigned int index
Index (just a number).
Definition: domain.h:58
void ec_slave_calc_transmission_delays_rec(ec_slave_t *slave, uint32_t *delay)
Recursively calculates transmission delays.
Definition: slave.c:1234
void ec_master_leave_idle_phase(ec_master_t *master)
Transition function from IDLE to ORPHANED phase.
Definition: master.c:819
Main device.
Definition: globals.h:237
EoE Init, Set IP Parameter Request.
Definition: ethernet.h:56
unsigned int skip_count
Number of requeues when not yet received.
Definition: datagram.h:112
int ec_master_init(ec_master_t *master, unsigned int index, const uint8_t *main_mac, const uint8_t *backup_mac, dev_t device_number, struct class *class, unsigned int debug_level)
Master constructor.
Definition: master.c:145
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2570
#define EOE_STH_PENDING
return flag from ecrt_master_eoe_process() to indicate there is something still pending.
Definition: master.h:132
int ec_device_init(ec_device_t *device, ec_master_t *master)
Constructor.
Definition: device.c:64
ec_slave_port_desc_t desc
Port descriptors.
Definition: slave.h:140
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:92
int ec_fsm_slave_exec(ec_fsm_slave_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Definition: fsm_slave.c:183
unsigned int rt_slave_requests
if True, slave requests are to be handled by calls to ecrt_master_exec_requests() from the applicatio...
Definition: master.h:295
unsigned int active
Master has been activated.
Definition: master.h:232
unsigned int string_count
Number of SII strings.
Definition: slave.h:176
struct list_head sent
Master list item for sent datagrams.
Definition: datagram.h:90
void ecrt_master_exec_slave_requests(ec_master_t *master)
Explicit call to process slave requests.
Definition: master.c:3975
int errno
Error number.
Definition: sdo_request.h:67
int ec_datagram_brd(ec_datagram_t *datagram, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT BRD datagram.
Definition: datagram.c:395
int ec_datagram_fpwr(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPWR datagram.
Definition: datagram.c:320
int ec_master_enter_operation_phase(ec_master_t *master)
Transition function from IDLE to OPERATION phase.
Definition: master.c:845
int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, uint8_t *target, size_t target_size, size_t *result_size, uint32_t *abort_code)
Executes an SDO upload request to read data from a slave.
Definition: master.c:3628
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:259
char ** strings
Strings in SII categories.
Definition: slave.h:175
wait_queue_head_t scan_queue
Queue for processes that wait for slave scanning.
Definition: master.h:269
ec_datagram_t sync_datagram
Datagram used for DC drift compensation.
Definition: master.h:254
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:80
struct device * class_device
Master class device.
Definition: master.h:208
int ec_datagram_fprd(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPRD datagram.
Definition: datagram.c:295
EtherCAT datagram structure.
void ec_master_queue_datagram(ec_master_t *master, ec_datagram_t *datagram)
Places a datagram in the datagram queue.
Definition: master.c:1105
int ec_slave_config_attach(ec_slave_config_t *sc)
Attaches the configuration to the addressed slave object.
Definition: slave_config.c:249
Broadcast Write.
Definition: datagram.h:59
CANopen dictionary request.
Definition: dict_request.h:48
static int ec_master_idle_thread(void *)
Master kernel thread function for IDLE phase.
Definition: master.c:1871
unsigned int scan_busy
true, if a slave rescan is in progress
Definition: ecrt.h:283
struct list_head configs
List of slave configurations.
Definition: master.h:243
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:135
ec_slave_config_t * dc_ref_config
Application-selected DC reference clock slave config.
Definition: master.h:260
ec_device_index_t device_index
Device via which the datagram shall be / was sent.
Definition: datagram.h:91
void ec_mbg_request_init(ec_mbg_request_t *req)
Mbox Gateway request constructor.
int ec_soe_request_alloc(ec_soe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: soe_request.c:150
void ec_sync_clear(ec_sync_t *sync)
Destructor.
Definition: sync.c:81
void ecrt_master_reset(ec_master_t *master)
Retry configuring slaves.
Definition: master.c:4641
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:100
int ec_fsm_master_idle(const ec_fsm_master_t *fsm)
Definition: fsm_master.c:164
void ec_master_clear_slaves(ec_master_t *master)
Clear all slaves.
Definition: master.c:606
Slave information.
Definition: ecrt.h:380
void ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:3440
struct list_head list
list item
Definition: ethernet.h:73
void ecrt_master_deactivate_slaves(ec_master_t *master)
Deactivates the slaves distributed clocks and sends the slaves into PREOP.
Definition: master.c:2889
struct list_head list
List item.
Definition: dict_request.h:49
Device statistics.
Definition: master.h:163
void ec_mbg_request_clear(ec_mbg_request_t *req)
Mbox Gateway request destructor.
uint8_t * ec_device_tx_data(ec_device_t *device)
Returns a pointer to the device&#39;s transmit memory.
Definition: device.c:356
u64 last_rx_bytes
Number of bytes received of last statistics cycle.
Definition: master.h:172
unsigned long output_jiffies
time of last output
Definition: master.h:156
ec_stats_t stats
Cyclic statistics.
Definition: master.h:311
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
Definition: module.c:355
void ec_read_mbox_lock_clear(ec_slave_t *slave)
Clears the mailbox lock.
Definition: slave.c:216
uint8_t valid_mbox_data
Received mailbox data is valid.
Definition: slave.h:297
Idle phase.
Definition: master.h:141
void ec_master_update_device_stats(ec_master_t *)
Updates the common device statistics.
Definition: master.c:1647
int ec_datagram_prealloc(ec_datagram_t *datagram, size_t size)
Allocates internal payload memory.
Definition: datagram.c:151
uint16_t effective_alias
Effective alias address.
Definition: slave.h:223
void ec_master_calc_transmission_delays(ec_master_t *master)
Calculates the bus transmission delays.
Definition: master.c:2630
uint8_t al_state
Current state of the slave.
Definition: ecrt.h:398
size_t data_size
Size of SDO data.
Definition: sdo_request.h:54
ec_lock_t master_sem
Master semaphore.
Definition: master.h:217
ec_slave_config_t * ecrt_master_slave_config(ec_master_t *master, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code)
Obtains a slave configuration.
Definition: master.c:3165
uint8_t ready
The slave is ready for external requests.
Definition: ecrt.h:401
uint8_t scan_busy
true, while the master is scanning the bus
Definition: ecrt.h:346
int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size, size_t *result_size, uint16_t *error_code)
Executes an SoE read request.
Definition: master.c:3870
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2554
void ec_master_eoe_start(ec_master_t *master)
Starts Ethernet over EtherCAT processing on demand.
Definition: master.c:1997
u64 tx_bytes
Number of bytes sent.
Definition: master.h:169
void(* app_send_cb)(void *)
Application&#39;s send datagrams callback.
Definition: master.h:328
size_t ec_master_send_datagrams(ec_master_t *master, ec_device_index_t device_index)
Sends the datagrams in the queue for a certain device.
Definition: master.c:1164
void * app_cb_data
Application callback data.
Definition: master.h:332
int ecrt_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
Definition: master.c:2814
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:2423
int16_t current_on_ebus
Used current in mA.
Definition: ecrt.h:387
Mailbox functionality.
void ec_master_clear_slave_configs(ec_master_t *)
Clear all slave configurations.
Definition: master.c:505
void ec_master_clear_domains(ec_master_t *)
Clear all domains.
Definition: master.c:649
void ec_master_find_dc_ref_clock(ec_master_t *)
Finds the DC reference clock.
Definition: master.c:2493
size_t ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
Definition: master.c:2986
struct list_head list
Used for execution list.
Definition: fsm_slave.h:65
uint8_t scan_required
The slave is being scanned.
Definition: ecrt.h:400
void ec_master_thread_stop(ec_master_t *master)
Stops the master thread.
Definition: master.c:732
void ec_sdo_request_init(ec_sdo_request_t *req)
SDO request constructor.
Definition: sdo_request.c:56
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:217
ec_datagram_t * ec_master_get_external_datagram(ec_master_t *master)
Searches for a free datagram in the external datagram ring.
Definition: master.c:1080
ec_datagram_t ext_datagram_ring[EC_EXT_RING_SIZE]
External datagram ring.
Definition: master.h:286
uint16_t sdo_count
Number of SDOs.
Definition: ecrt.h:403
struct list_head list
List item.
Definition: sdo_request.h:49
#define EC_MAX_STRING_LENGTH
Maximum string length.
Definition: ecrt.h:214
void ec_datagram_init(ec_datagram_t *datagram)
Constructor.
Definition: datagram.c:88
static unsigned long timeout_jiffies
Frame timeout in jiffies.
Definition: master.c:93
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, const uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave.
Definition: master.c:3459
void ec_rtdm_dev_clear(ec_rtdm_dev_t *rtdm_dev)
Clear an RTDM device.
Definition: rtdm.c:118
void ec_cdev_clear(ec_cdev_t *cdev)
Destructor.
Definition: cdev.c:144
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:142
Queued for sending.
Definition: datagram.h:76
unsigned int link_up
true, if at least one Ethernet link is up.
Definition: ecrt.h:281
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:125
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:143
Timed out (dequeued).
Definition: datagram.h:79
wait_queue_head_t config_queue
Queue for processes that wait for slave configuration.
Definition: master.h:275
#define EC_EXT_RING_SIZE
Size of the external datagram ring.
Definition: master.h:119
void ec_master_reboot_slaves(ec_master_t *master)
Requests that all slaves on this master be rebooted (if supported).
Definition: master.c:1067
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:678
uint16_t next_slave
Ring position of next DC slave on that port.
Definition: ecrt.h:393
void ec_master_calc_topology(ec_master_t *master)
Calculates the bus topology.
Definition: master.c:2606
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:249
void ec_slave_request_state(ec_slave_t *slave, ec_slave_state_t state)
Request a slave state and resets the error flag.
Definition: slave.c:436
ec_mbox_data_t mbox_voe_data
Received mailbox data for VoE.
Definition: slave.h:294
ec_datagram_t ref_sync_datagram
Datagram used for synchronizing the reference clock to the master clock.
Definition: master.h:252
void ec_master_output_stats(ec_master_t *master)
Output master statistics.
Definition: master.c:1584
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:257
#define EC_FIND_DOMAIN
Common implementation for ec_master_find_domain() and ec_master_find_domain_const().
Definition: master.c:2376
u64 rx_count
Number of frames received.
Definition: master.h:166
void ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2926
unsigned int al_states
Application-layer states of all slaves.
Definition: ecrt.h:272
uint8_t upstream_port
Index of upstream (master facing) port.
Definition: ecrt.h:397
uint8_t * data
Datagram payload.
Definition: datagram.h:95
#define EC_FIND_SLAVE
Common implementation for ec_master_find_slave() and ec_master_find_slave_const().
Definition: master.c:2238
#define EC_BYTE_TRANSMISSION_TIME_NS
Time to send a byte in nanoseconds.
Definition: globals.h:56
uint16_t alias
The slaves alias if not equal to 0.
Definition: ecrt.h:386
int ecrt_master(ec_master_t *master, ec_master_info_t *master_info)
Obtains master information.
Definition: master.c:3200
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
void ec_dict_request_init(ec_dict_request_t *req)
Dictionary request constructor.
Definition: dict_request.c:43
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size, uint16_t *error_code)
Executes an SoE write request.
Definition: master.c:3794
struct list_head dict_requests
Dictionary read requests.
Definition: slave.h:280
void ec_master_slaves_not_available(ec_master_t *master)
Set flag to say that the slaves are not available for slave request processing.
Definition: master.c:585
EtherCAT slave configuration.
Definition: slave_config.h:118
struct list_head queue
Master datagram queue item.
Definition: datagram.h:89
uint32_t product_code
Product-Code stored on the slave.
Definition: ecrt.h:383
EtherCAT device structure.
void(* app_receive_cb)(void *)
Application&#39;s receive datagrams callback.
Definition: master.h:330
unsigned long pcap_size
Pcap buffer size in bytes.
Definition: module.c:67
void ec_soe_request_write(ec_soe_request_t *req)
Request a write operation.
Definition: soe_request.c:245
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:93
int ec_fsm_master_exec(ec_fsm_master_t *fsm)
Executes the current state of the state machine.
Definition: fsm_master.c:145
void ec_soe_request_init(ec_soe_request_t *req)
SoE request constructor.
Definition: soe_request.c:56
EtherCAT slave configuration structure.
ec_sii_t sii
Extracted SII data.
Definition: slave.h:207
ec_slave_config_t * ecrt_master_slave_config_err(ec_master_t *master, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code)
Same as ecrt_master_slave_config(), but with ERR_PTR() return value.
Definition: master.c:3107
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:217
void ec_device_poll(ec_device_t *device)
Calls the poll function of the assigned net_device.
Definition: device.c:536
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
int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time)
Get the lower 32 bit of the reference clock system time.
Definition: master.c:3351
Unused and should not be queued (dequeued).
Definition: datagram.h:81
Master information.
Definition: ecrt.h:343
unsigned int index
Index.
Definition: master.h:203
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
Definition: master.c:2294
void ecrt_master_64bit_reference_clock_time_queue(ec_master_t *master)
Queues the 64bit dc reference slave clock time value datagram for sending.
Definition: master.c:3407
Error while sending/receiving (dequeued).
Definition: datagram.h:80
Auto Increment Physical Write.
Definition: datagram.h:53
uint8_t address[EC_ADDR_LEN]
Recipient address.
Definition: datagram.h:94
u64 last_tx_bytes
Number of bytes sent of last statistics cycle.
Definition: master.h:170
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:127
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:161
void ec_domain_init(ec_domain_t *domain, ec_master_t *master, unsigned int index)
Domain constructor.
Definition: domain.c:63
PREOP state (mailbox communication, no IO)
Definition: globals.h:164
int ecrt_master_sdo_download_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, const uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave via complete access.
Definition: master.c:3543
void ec_slave_config_clear(ec_slave_config_t *sc)
Slave configuration destructor.
Definition: slave_config.c:104
Backup device.
Definition: globals.h:238
struct list_head list
List item.
Definition: pdo.h:50
Received (dequeued).
Definition: datagram.h:78
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:71
ec_fsm_master_t fsm
Master state machine.
Definition: master.h:229
ec_cdev_t cdev
Master character device.
Definition: master.h:206
u64 rx_bytes
Number of bytes received.
Definition: master.h:171
#define EC_DATAGRAM_FOOTER_SIZE
Size of an EtherCAT datagram footer.
Definition: globals.h:84
uint8_t scan_required
Scan required.
Definition: slave.h:270
#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
uint16_t position
Offset of the slave in the ring.
Definition: ecrt.h:381
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:190
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
Definition: slave.h:171
uint32_t receive_time
Receive time on DC transmission delay measurement.
Definition: ecrt.h:391
int ec_master_calc_topology_rec(ec_master_t *master, ec_slave_t *upstream_slave, unsigned int *slave_position)
Calculates the bus topology; recursion function.
Definition: master.c:2563
unsigned int config_changed
The configuration changed.
Definition: master.h:233
EtherCAT master.
Definition: master.h:202
unsigned int injection_seq_rt
Datagram injection sequence number for the realtime side.
Definition: master.h:236
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
Configured Address Physical Write.
Definition: datagram.h:56
ec_slave_state_t requested_state
Requested application state.
Definition: slave.h:236
#define FORCE_OUTPUT_CORRUPTED
Always output corrupted frames.
Definition: master.c:77
#define EC_READ_U64(DATA)
Read a 64-bit unsigned value from EtherCAT data.
Definition: ecrt.h:2586
uint8_t index
Index (set by master).
Definition: datagram.h:99
void ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:3374
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:219
void ec_slave_config_load_default_sync_config(ec_slave_config_t *sc)
Loads the default PDO assignment from the slave object.
Definition: slave_config.c:344
ec_lock_t scan_sem
Semaphore protecting the scan_busy variable and the allow_scan flag.
Definition: master.h:267
unsigned int config_busy
State of slave configuration.
Definition: master.h:272
void ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
Definition: sdo_request.c:243
void ec_master_inject_external_datagrams(ec_master_t *master)
Injects external datagrams that fit into the datagram queue.
Definition: master.c:938
ec_lock_t io_sem
Semaphore used in IDLE phase.
Definition: master.h:323
void ec_fsm_master_clear(ec_fsm_master_t *fsm)
Destructor.
Definition: fsm_master.c:103
int ec_eoe_is_open(const ec_eoe_t *eoe)
Returns the state of the device.
Definition: ethernet.c:693
void ec_device_clear_stats(ec_device_t *device)
Clears the frame statistics.
Definition: device.c:419
char * name
Slave name.
Definition: slave.h:183
void ec_master_set_send_interval(ec_master_t *master, unsigned int send_interval)
Sets the expected interval between calls to ecrt_master_send and calculates the maximum amount of dat...
Definition: master.c:1052
unsigned long jiffies_received
Jiffies, when the datagram was received.
Definition: datagram.h:110
ec_mbox_data_t mbox_coe_data
Received mailbox data for CoE.
Definition: slave.h:291
void ec_slave_config_expire_disconnected_requests(ec_slave_config_t *sc)
Expires any requests that have been started on a detached slave.
Definition: slave_config.c:604
EtherCAT domain.
Definition: domain.h:54
ec_mbox_data_t mbox_soe_data
Received mailbox data for SoE.
Definition: slave.h:293
size_t payload_size
Size of the mailbox response payload data.
Definition: datagram.h:125
void ec_master_eoe_stop(ec_master_t *master)
Stops the Ethernet over EtherCAT processing.
Definition: master.c:2036
void(* send_cb)(void *)
Current send datagrams callback.
Definition: master.h:325
uint32_t vendor_id
Vendor ID.
Definition: slave.h:160
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
Definition: slave.h:145
struct task_struct * thread
Master thread.
Definition: master.h:316
unsigned int queue_datagram
the datagram is ready for queuing
Definition: ethernet.h:77
void ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index, uint8_t subindex)
Set the SDO index and subindex and prepare for non-complete-access.
Definition: sdo_request.c:187
ec_slave_t * dc_ref_clock
DC reference clock slave.
Definition: master.h:262
int ec_cdev_init(ec_cdev_t *cdev, ec_master_t *master, dev_t dev_num)
Constructor.
Definition: cdev.c:118
struct list_head pdos
SII [RT]XPDO categories.
Definition: slave.h:194
unsigned int force_config
Force (re-)configuration.
Definition: slave.h:240
struct list_head sii_images
List of slave SII images.
Definition: master.h:247
#define EOE_STH_TO_SEND
return flag from ecrt_master_eoe_process() to indicate there is something to send.
Definition: master.h:124
int ecrt_master_rt_slave_requests(ec_master_t *master, unsigned int rt_slave_requests)
Selects whether to process slave requests by the application or the master.
Definition: master.c:3954
void ec_sii_image_clear(ec_sii_image_t *sii_image)
Clear the SII data.
Definition: master.c:522
#define EC_SDO_INJECTION_TIMEOUT
SDO injection timeout in microseconds.
Definition: globals.h:50
void ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:3035
#define EC_MAX_DATA_SIZE
Resulting maximum data size of a single datagram in a frame.
Definition: globals.h:95
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
void ec_master_init_static(void)
Static variables initializer.
Definition: master.c:124
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
ec_internal_request_state_t state
SDO request state.
Definition: dict_request.h:50
void ec_mbg_request_run(ec_mbg_request_t *req)
Request to run.
void ec_master_slaves_available(ec_master_t *master)
Set flag to say that the slaves are now available for slave request processing.
Definition: master.c:597
void ec_datagram_clear(ec_datagram_t *datagram)
Destructor.
Definition: datagram.c:119