Compare commits

..

22 Commits

Author SHA1 Message Date
Florian Pose b709e58147 Version bump to 1.6.9 2026-03-26 17:47:12 +01:00
Florian Pose 15883228f9 Merge branch 'fix-suse-16' into 'stable-1.6'
Driver fixes for openSUSE Leap 16.0

See merge request etherlab.org/ethercat!192
2026-03-26 17:45:44 +01:00
Florian Pose 9c63faf50d Fixed igb for SUSE kernel 6.12 2026-03-26 17:38:46 +01:00
Florian Pose bf706b737d Fixed genet for SUSE 16.0. 2026-03-26 17:26:45 +01:00
Florian Pose cf19168844 Cherry-picked MR 188 (injection-semaphore) from 1.7. 2026-03-26 16:41:43 +01:00
Florian Pose 98563a2f0d Merge branch 'no-config-necessary' into 'stable-1.6'
Do not require .config to exist in kernel sources

Closes #198

See merge request etherlab.org/ethercat!186
2026-03-24 17:13:53 +01:00
Florian Pose db526666f3 At least check for Makefile. 2026-03-24 17:07:12 +01:00
Florian Pose 1e61b8400c Minor: Improved comments in DC user example. 2026-03-24 17:05:00 +01:00
Florian Pose 6869c2bab8 Merge branch 'stable-1.6-kernel615' into 'stable-1.6'
tty: Implemented new timer interface since kernel 6.15.

See merge request etherlab.org/ethercat!187
2026-03-16 14:47:06 +01:00
Bernd Kuhls e32e99f8b8 tty: Implemented new timer interface since kernel 6.15.
Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
2026-03-15 20:06:42 +01:00
Florian Pose 7a7d7f051b Merge branch 'calc-dc-after-attach' into 'stable-1.6'
Attach slaves before calculating DCs

Closes #212

See merge request etherlab.org/ethercat!185
2026-03-13 15:17:53 +01:00
Florian Pose 607d0fd1af Merge branch 'discard-eoe' into 'stable-1.6'
Discard EoE traffic if EoE is disabled

See merge request etherlab.org/ethercat!184
2026-03-13 15:16:29 +01:00
Florian Pose 212cb59d58 Do not require .config to exist in kernel sources. 2026-03-12 12:01:21 +01:00
Florian Pose c76b02ae2e Attach slaves before calculating DCs. 2026-03-12 11:36:37 +01:00
Florian Pose c8c23aa448 Discard EoE traffic in CoE statemachine, if EoE is disabled. 2026-03-10 09:24:13 +01:00
Florian Pose 4e5b661674 Merge branch 'fix-6.19' into 'stable-1.6'
Linux 6.19.0 support

Closes #200

See merge request etherlab.org/ethercat!183
2026-03-09 15:02:17 +01:00
Nicola Fontana c42c9cf8bc Linux 6.19.0 support
Commit 89aec171d9d1ab168e43fcf9754b82e4c0aef9b9 (part of linux kernel
6.19.0-rc1) introduced an arbitrarily sized sockaddr struct to be used
instead of the classical one.

Closes #200
2026-03-08 15:54:00 +01:00
Florian Pose 3ccae1d47d Updated NEWS.md 2026-03-03 08:56:21 +01:00
Florian Pose bde53bc4f3 Use /sbin/ip as default 2026-03-03 08:52:53 +01:00
Florian Pose f16c0ff3c3 Merge branch 'custom-paths' into 'stable-1.6'
Allow to customize kmod path and ip command

Closes #206

See merge request etherlab.org/ethercat!182
2026-03-03 08:51:06 +01:00
Nicola Fontana b86d2163f1 Fix #206: allow to customize utilities from configure
`ethercatctl` calls some utilites actually hardcoded in the script.
Provide a way to customize them from configure.

The default values are choosen to be backward compatible with the old
behavior, but more sensible values would be preferred, e.g.:

OPTION      ACTUAL DEFAULT      PREFERRED DEFAULT
kmod-dir    /sbin               $sbindir
ip-cmd      /bin/ip             $sbindir/ip

In a major future release this can be changed.
2026-03-02 12:09:59 +01:00
Nicola Fontana 90f9feb0ad Improve help string consistency
* Move default values from comments to help strings
* Use the "... [default=...]" convention everywhere
* Change "Enable ... driver" to more correct "Build ... driver"
* Fix --enable-dwmac-intel help string
* Fix --enable-fakeuserlib help string
* Change --disable-initd to --enable-initd to avoid confusion with
  `--disable-initd [default=yes]`.
2026-03-02 11:44:15 +01:00
13 changed files with 240 additions and 70 deletions

13
NEWS.md
View File

@ -1,3 +1,16 @@
# Version 1.6.9
- Protect datagram injection mechanism against re-ordering.
- Fixed for genet and igb drivers for openSUSE Leap 16.0 kernel 6.12.
- tty: Implemented new timer interface since kernel 6.15.
- Do not require .config to exist in kernel sources.
- Fix: Attach slaves before calculating DCs.
- Discard EoE traffic in CoE statemachine, if EoE is disabled.
- Support for Linux 6.19
- Added `--with-kmod-dir` and `--with-ip-cmd` configuration switches
to specify the paths of the tools used in the `ethercatctl` script.
- Changed the default path of the `ip` command to `/sbin/ip`.
# Version 1.6.8
- Fixed usage of `FAKE_EC_HOMEDIR` variable in fake library.

View File

@ -28,7 +28,7 @@ AC_PREREQ([2.59])
# - Check for complete Doxygen comments
# - Update version number below
#
AC_INIT([ethercat], [1.6.8], [fp@igh.de])
AC_INIT([ethercat], [1.6.9], [fp@igh.de])
AC_CONFIG_AUX_DIR([autoconf])
AM_INIT_AUTOMAKE([-Wall -Wno-override -Werror dist-bzip2 subdir-objects foreign])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@ -59,7 +59,7 @@ AC_MSG_CHECKING([whether to build kernel modules])
AC_ARG_ENABLE([kernel],
AS_HELP_STRING([--enable-kernel],
[Enable building kernel modules]),
[Enable building kernel modules [default=yes]]),
[
case "${enableval}" in
yes) enablekernel=1
@ -90,7 +90,7 @@ if test "x$enablekernel" = "x1"; then
AC_ARG_WITH([linux-dir],
AS_HELP_STRING([--with-linux-dir=<DIR>],
[Linux kernel sources @<:@running kernel@:>@]),
[Linux kernel sources [running kernel]]),
[
sourcedir=[$withval]
],
@ -107,9 +107,9 @@ AC_ARG_WITH([linux-dir],
AC_MSG_CHECKING([for Linux kernel sources])
if test \! -r ${sourcedir}/.config; then
if test \! -r ${sourcedir}/Makefile; then
echo
AC_MSG_ERROR([No configured Linux kernel sources in $sourcedir])
AC_MSG_ERROR([No Linux kernel sources in $sourcedir])
fi
# Try to get kernel release string
@ -127,7 +127,7 @@ fi
if test -z "$kernelrelease"; then
echo
AC_MSG_ERROR([Failed to extract Linux kernel version!])
AC_MSG_ERROR([Failed to extract Linux kernel version! Does ${sourcedir} contain prepared kernel sources?])
fi
if test ${kernelrelease%%.*} -gt 2; then
@ -150,7 +150,7 @@ fi
AC_ARG_WITH([module-dir],
AS_HELP_STRING([--with-module-dir=<DIR>],
[Linux module installation dir. Default: ethercat]),
[Linux module installation dir [default=ethercat]]),
[moddir=[$withval]],
[moddir="ethercat"]
)
@ -167,7 +167,7 @@ AC_MSG_CHECKING([whether to verify native driver resources])
AC_ARG_ENABLE([driver-resource-verifying],
AS_HELP_STRING([--enable-driver-resource-verifying],
[Verify resource (de-)allocation in native drivers]),
[Verify resource (de-)allocation in native drivers [default=no]]),
[
case "${enableval}" in
yes) enableverifying=1
@ -196,7 +196,7 @@ AC_SUBST(ENABLE_DRIVER_RESOURCE_VERIFYING, [$enableverifying])
AC_ARG_ENABLE([generic],
AS_HELP_STRING([--enable-generic],
[Enable generic Ethernet driver]),
[Build generic Ethernet driver [default=enable-kernel]]),
[
case "${enableval}" in
yes) enablegeneric=1
@ -219,7 +219,7 @@ AC_SUBST(ENABLE_GENERIC, [$enablegeneric])
AC_ARG_ENABLE([8139too],
AS_HELP_STRING([--enable-8139too],
[Enable 8139too driver]),
[Build 8139too driver [default=no]]),
[
case "${enableval}" in
yes) enable8139too=1
@ -230,7 +230,7 @@ AC_ARG_ENABLE([8139too],
;;
esac
],
[enable8139too=0] # disabled by default
[enable8139too=0]
)
AM_CONDITIONAL(ENABLE_8139TOO, test "x$enable8139too" = "x1")
@ -272,7 +272,7 @@ AC_SUBST(KERNEL_8139TOO, [$kernel8139too])
AC_ARG_ENABLE([e100],
AS_HELP_STRING([--enable-e100],
[Enable e100 driver]),
[Build e100 driver [default=no]]),
[
case "${enableval}" in
yes) enablee100=1
@ -283,7 +283,7 @@ AC_ARG_ENABLE([e100],
;;
esac
],
[enablee100=0] # disabled by default
[enablee100=0]
)
AM_CONDITIONAL(ENABLE_E100, test "x$enablee100" = "x1")
@ -325,7 +325,7 @@ AC_SUBST(KERNEL_E100, [$kernele100])
AC_ARG_ENABLE([e1000],
AS_HELP_STRING([--enable-e1000],
[Enable e1000 driver]),
[Build e1000 driver [default=no]]),
[
case "${enableval}" in
yes) enablee1000=1
@ -336,7 +336,7 @@ AC_ARG_ENABLE([e1000],
;;
esac
],
[enablee1000=0] # disabled by default
[enablee1000=0]
)
AM_CONDITIONAL(ENABLE_E1000, test "x$enablee1000" = "x1")
@ -378,7 +378,7 @@ AC_SUBST(KERNEL_E1000, [$kernele1000])
AC_ARG_ENABLE([e1000e],
AS_HELP_STRING([--enable-e1000e],
[Enable e1000e driver]),
[Build e1000e driver [default=no]]),
[
case "${enableval}" in
yes) enablee1000e=1
@ -389,7 +389,7 @@ AC_ARG_ENABLE([e1000e],
;;
esac
],
[enablee1000e=0] # disabled by default
[enablee1000e=0]
)
AM_CONDITIONAL(ENABLE_E1000E, test "x$enablee1000e" = "x1")
@ -451,7 +451,7 @@ AC_SUBST(E1000E_LAYOUT, [$e1000elayout])
AC_ARG_ENABLE([genet],
AS_HELP_STRING([--enable-genet],
[Enable genet driver (for Raspi 4)]),
[Build genet driver for Raspi 4 [default=no]]),
[
case "${enableval}" in
yes) enablegenet=1
@ -462,7 +462,7 @@ AC_ARG_ENABLE([genet],
;;
esac
],
[enablegenet=0] # disabled by default
[enablegenet=0]
)
AM_CONDITIONAL(ENABLE_GENET, test "x$enablegenet" = "x1")
@ -497,7 +497,7 @@ AC_SUBST(KERNEL_GENET, [$kernelgenet])
AC_ARG_ENABLE([igb],
AS_HELP_STRING([--enable-igb],
[Enable igb driver]),
[Build igb driver [default=no]]),
[
case "${enableval}" in
yes) enableigb=1
@ -508,7 +508,7 @@ AC_ARG_ENABLE([igb],
;;
esac
],
[enableigb=0] # disabled by default
[enableigb=0]
)
AM_CONDITIONAL(ENABLE_IGB, test "x$enableigb" = "x1")
@ -544,7 +544,7 @@ AC_SUBST(KERNEL_IGB, [$kerneligb])
AC_ARG_ENABLE([igc],
AS_HELP_STRING([--enable-igc],
[Enable igc driver]),
[Build igc driver [default=no]]),
[
case "${enableval}" in
yes) enableigc=1
@ -555,7 +555,7 @@ AC_ARG_ENABLE([igc],
;;
esac
],
[enableigc=0] # disabled by default
[enableigc=0]
)
AM_CONDITIONAL(ENABLE_IGC, test "x$enableigc" = "x1")
@ -606,7 +606,7 @@ has_r8169_leds=0
AC_ARG_ENABLE([r8169],
AS_HELP_STRING([--enable-r8169],
[Enable r8169 driver]),
[Build r8169 driver [default=no]]),
[
case "${enableval}" in
yes) enable_r8169=1
@ -617,7 +617,7 @@ AC_ARG_ENABLE([r8169],
;;
esac
],
[enable_r8169=0] # disabled by default
[enable_r8169=0]
)
AM_CONDITIONAL(ENABLE_R8169, test "x$enable_r8169" = "x1")
@ -681,7 +681,7 @@ enablestmmac=0
AC_ARG_ENABLE([stmmac-pci],
AS_HELP_STRING([--enable-stmmac-pci],
[Enable stmmac driver]),
[Build stmmac driver [default=no]]),
[
case "${enableval}" in
yes) enablestmmacpci=1
@ -693,7 +693,7 @@ AC_ARG_ENABLE([stmmac-pci],
;;
esac
],
[enablestmmacpci=0] # disabled by default
[enablestmmacpci=0]
)
AM_CONDITIONAL(ENABLE_STMMACPCI, test "x$enablestmmacpci" = "x1")
@ -701,7 +701,7 @@ AC_SUBST(ENABLE_STMMACPCI, [$enablestmmacpci])
AC_ARG_ENABLE([dwmac-intel],
AS_HELP_STRING([--enable-dwmac-intel],
[Enable stmmac driver]),
[Build dwmac intel driver [default=no]]),
[
case "${enableval}" in
yes) enabledwmacintel=1
@ -713,7 +713,7 @@ AC_ARG_ENABLE([dwmac-intel],
;;
esac
],
[enabledwmacintel=0] # disabled by default
[enabledwmacintel=0]
)
AM_CONDITIONAL(ENABLE_DWMACINTEL, test "x$enabledwmacintel" = "x1")
@ -764,7 +764,7 @@ AC_MSG_CHECKING([whether to build the CCAT driver])
AC_ARG_ENABLE([ccat],
AS_HELP_STRING([--enable-ccat],
[Enable CCAT driver]),
[Build CCAT driver [default=no]]),
[
case "${enableval}" in
yes) enableccat=1
@ -775,7 +775,7 @@ AC_ARG_ENABLE([ccat],
;;
esac
],
[enableccat=0] # disabled by default
[enableccat=0]
)
if test "x${enableccat}" = "x1"; then
@ -848,7 +848,7 @@ AC_ARG_WITH([xenomai-dir],
AC_ARG_WITH([xenomai-config],
AS_HELP_STRING([--with-xenomai-config=<CMD>],
[Xenomai config invokation, default to xenomai-dir/bin/xeno-config]),
[Xenomai config invocation [default=xenomai-dir/bin/xeno-config]]),
[
xenomaiconfig=[$withval]
],
@ -946,7 +946,7 @@ AC_MSG_CHECKING([whether to build the debug interface])
AC_ARG_ENABLE([debug-if],
AS_HELP_STRING([--enable-debug-if],
[Create a debug interface for each master @<:@NO@:>@]),
[Create a debug interface for each master [default=no]]),
[
case "${enableval}" in
yes) dbg=1
@ -978,7 +978,7 @@ AC_MSG_CHECKING([whether to build the debug ring])
AC_ARG_ENABLE([debug-ring],
AS_HELP_STRING([--enable-debug-ring],
[Create a debug ring to record frames @<:@NO@:>@]),
[Create a debug ring to record frames [default=no]]),
[
case "${enableval}" in
yes) debugring=1
@ -1007,7 +1007,7 @@ AC_MSG_CHECKING([whether to build with EoE support])
AC_ARG_ENABLE([eoe],
AS_HELP_STRING([--enable-eoe],
[Enable EoE support (default: yes)]),
[Enable EoE support [default=yes]]),
[
case "${enableval}" in
yes) eoe=1
@ -1039,7 +1039,7 @@ AC_MSG_CHECKING([whether to use the CPU timestamp counter])
AC_ARG_ENABLE([cycles],
AS_HELP_STRING([--enable-cycles],
[Use CPU timestamp counter (default: no)]),
[Use CPU timestamp counter [default=no]]),
[
case "${enableval}" in
yes) cycles=1
@ -1068,7 +1068,7 @@ AC_MSG_CHECKING([whether to use high-resolution timers for scheduling])
AC_ARG_ENABLE([hrtimer],
AS_HELP_STRING([--enable-hrtimer],
[Use high-resolution timer for scheduling (default: no)]),
[Use high-resolution timer for scheduling [default=no]]),
[
case "${enableval}" in
yes) hrtimer=1
@ -1097,7 +1097,7 @@ AC_MSG_CHECKING([whether to read alias addresses from registers])
AC_ARG_ENABLE([regalias],
AS_HELP_STRING([--enable-regalias],
[Read alias adresses from register (default: no)]),
[Read alias adresses from register [default=no]]),
[
case "${enableval}" in
yes) regalias=1
@ -1126,7 +1126,7 @@ AC_MSG_CHECKING([whether to build the command-line tool])
AC_ARG_ENABLE([tool],
AS_HELP_STRING([--enable-tool],
[Build command-line tool (default: yes)]),
[Build command-line tool [default=yes]]),
[
case "${enableval}" in
yes) tool=1
@ -1156,7 +1156,7 @@ AC_MSG_CHECKING([whether to build the userspace library])
AC_ARG_ENABLE([userlib],
AS_HELP_STRING([--enable-userlib],
[Generation of the userspace library (default: yes)]),
[Generation of userspace library [default=yes]]),
[
case "${enableval}" in
yes) userlib=1
@ -1186,7 +1186,7 @@ AC_MSG_CHECKING([whether to build the fake userspace library])
AC_ARG_ENABLE([fakeuserlib],
AS_HELP_STRING([--enable-fakeuserlib],
[Generation of the userspace library (default: no)]),
[Generation of fake userspace library [default=no]]),
[
case "${enableval}" in
yes) fakeuserlib=1
@ -1217,7 +1217,7 @@ AC_MSG_CHECKING([whether to build the tty driver])
AC_ARG_ENABLE([tty],
AS_HELP_STRING([--enable-tty],
[Generation of the ec_tty module (default: no)]),
[Generation of the ec_tty module [default=no]]),
[
case "${enableval}" in
yes) tty=1
@ -1248,7 +1248,7 @@ AC_MSG_CHECKING([whether to allow identification wildcards])
AC_ARG_ENABLE([wildcards],
AS_HELP_STRING([--enable-wildcards],
[Enable vendor ID / product code wildcards (default: no)]),
[Enable vendor ID / product code wildcards [default=no]]),
[
case "${enableval}" in
yes) wildcards=1
@ -1276,7 +1276,7 @@ fi
AC_ARG_WITH([devices],
AS_HELP_STRING([--with-devices=<NUMBER>],
[Number of Ethernet devices per master. Default: 1]),
[Number of Ethernet devices per master [default=1]]),
[
devices=[$withval]
],
@ -1308,7 +1308,7 @@ AC_MSG_CHECKING([whether to assign the SII to PDI])
AC_ARG_ENABLE([sii-assign],
AS_HELP_STRING([--enable-sii-assign],
[Enable SII assignment to PDI (default: yes)]),
[Enable SII assignment to PDI [default=yes]]),
[
case "${enableval}" in
yes) siiassign=1
@ -1337,7 +1337,7 @@ AC_MSG_CHECKING([whether to syslog in realtime context])
AC_ARG_ENABLE([rt-syslog],
AS_HELP_STRING([--enable-rt-syslog],
[Enable RT syslog (default: yes)]),
[Enable RT syslog [default=yes]]),
[
case "${enableval}" in
yes) rtsyslog=1
@ -1363,8 +1363,8 @@ fi
#-----------------------------------------------------------------------------
AC_ARG_ENABLE([initd],
AS_HELP_STRING([--disable-initd],
[Disable /etc/init.d script support (default: enabled)])
AS_HELP_STRING([--enable-initd],
[Install /etc/init.d scripts [default=yes]])
)
AM_CONDITIONAL(HAVE_INITD, test "x$enable_initd" != "xno")
@ -1397,6 +1397,32 @@ esac
AM_CONDITIONAL(HAVE_SYSTEMD, test "x$with_systemdsystemunitdir" != "x")
AC_SUBST(systemdsystemunitdir, [$with_systemdsystemunitdir])
#-----------------------------------------------------------------------------
# System utilities
#-----------------------------------------------------------------------------
AC_ARG_WITH([kmod-dir],
AS_HELP_STRING([--with-kmod-dir=<DIR>],
[Path to kernel module utilities [default=/sbin]]),
[kmoddir=[$withval]],
[kmoddir="/sbin"]
)
AC_MSG_CHECKING([for path to kernel modules])
AC_MSG_RESULT([$kmoddir])
AC_SUBST(kmoddir, [$kmoddir])
AC_ARG_WITH([ip-cmd],
AS_HELP_STRING([--with-ip-cmd=<CMD>],
['ip' command to use [default=/sbin/ip]]),
[ipcmd=[$withval]],
[ipcmd="/sbin/ip"]
)
AC_MSG_CHECKING([for ip command])
AC_MSG_RESULT([$ipcmd])
AC_SUBST(ipcmd, [$ipcmd])
#-----------------------------------------------------------------------------
AC_CONFIG_FILES([

View File

@ -234,7 +234,11 @@ int ec_gen_device_create_socket(
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons(ETH_P_ETHERCAT);
sa.sll_ifindex = desc->ifindex;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 19, 0)
ret = kernel_bind(dev->socket, (struct sockaddr_unsized *) &sa, sizeof(sa));
#else
ret = kernel_bind(dev->socket, (struct sockaddr *) &sa, sizeof(sa));
#endif
if (ret) {
printk(KERN_ERR PFX "Failed to bind() socket to interface"
" (ret = %i).\n", ret);

View File

@ -2459,7 +2459,11 @@ static int bcmgenet_rx_poll(struct napi_struct *napi, int budget)
if (ring->dim.use_dim) {
dim_update_sample(ring->dim.event_ctr, ring->dim.packets,
ring->dim.bytes, &dim_sample);
#ifdef CONFIG_SUSE_KERNEL
net_dim(&ring->dim.dim, &dim_sample);
#else
net_dim(&ring->dim.dim, dim_sample);
#endif
}
return work_done;

View File

@ -2513,6 +2513,9 @@ static int igb_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr, u16 vid,
u16 flags,
#ifdef CONFIG_SUSE_KERNEL
bool *notified,
#endif
struct netlink_ext_ack *extack)
{
/* guarantee we can provide a unique filter for the unicast address */

View File

@ -1,6 +1,6 @@
/*****************************************************************************
*
* Copyright (C) 2007-2022 Florian Pose, Ingenieurgemeinschaft IgH
* Copyright (C) 2007-2026 Florian Pose, Ingenieurgemeinschaft IgH
*
* This file is part of the IgH EtherCAT Master.
*
@ -300,8 +300,14 @@ int main(int argc, char **argv)
if (off_counter_out < 0)
return -1;
// configure SYNC signals for this slave
ecrt_slave_config_dc(sc, 0x0700, PERIOD_NS, 4400000, 0, 0);
// configure SYNC0/SYNC1 interrupts for this slave
ecrt_slave_config_dc(sc,
0x0700, // AssignActivate (see vendor docs)
PERIOD_NS, // SYNC0 cycle time [ns]
4400000, // SYNC0 shift time [ns]
0, // SYNC1 cycle time [ns]
0 // SYNC1 shift time [ns]
);
printf("Activating master...\n");
if (ecrt_master_activate(master))

View File

@ -233,7 +233,11 @@ static void __exit cleanup_mini_module(void)
{
printk(KERN_INFO PFX "Stopping...\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
timer_delete_sync(&timer);
#else
del_timer_sync(&timer);
#endif
free_serial_devices();

View File

@ -539,6 +539,16 @@ void ec_fsm_coe_dict_response(
return;
}
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_dict_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) {
EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
mbox_prot);
@ -821,6 +831,16 @@ void ec_fsm_coe_dict_desc_response(
return;
}
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_dict_desc_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) {
EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
mbox_prot);
@ -1057,6 +1077,16 @@ void ec_fsm_coe_dict_entry_response(
return;
}
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_dict_entry_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) {
EC_SLAVE_ERR(slave, "Received mailbox protocol"
" 0x%02X as response.\n", mbox_prot);
@ -1574,6 +1604,16 @@ void ec_fsm_coe_down_response(
return;
}
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_down_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) {
request->errno = EIO;
fsm->state = ec_fsm_coe_error;
@ -1752,6 +1792,16 @@ void ec_fsm_coe_down_seg_response(
return;
}
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_down_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) {
request->errno = EIO;
fsm->state = ec_fsm_coe_error;
@ -2114,10 +2164,15 @@ void ec_fsm_coe_up_response(
return;
}
if (master->debug_level) {
EC_SLAVE_DBG(slave, 1, "Upload response:\n");
ec_print_data(data, rec_size);
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_up_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) {
request->errno = EIO;
@ -2135,6 +2190,11 @@ void ec_fsm_coe_up_response(
return;
}
if (master->debug_level) {
EC_SLAVE_DBG(slave, 1, "Upload response:\n");
ec_print_data(data, rec_size);
}
if (rec_size < 6) {
request->errno = EIO;
fsm->state = ec_fsm_coe_error;
@ -2411,10 +2471,15 @@ void ec_fsm_coe_up_seg_response(
return;
}
if (master->debug_level) {
EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
ec_print_data(data, rec_size);
#ifndef EC_EOE
if (mbox_prot == EC_MBOX_TYPE_EOE) {
// discard EoE message and wait for the next reponse
ec_slave_mbox_prepare_check(slave, datagram); // can not fail.
fsm->retries = EC_FSM_RETRIES;
fsm->state = ec_fsm_coe_up_seg_check;
return;
}
#endif
if (mbox_prot != EC_MBOX_TYPE_COE) {
EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
@ -2432,6 +2497,12 @@ void ec_fsm_coe_up_seg_response(
return;
}
if (master->debug_level) {
EC_SLAVE_DBG(slave, 1, "Upload segment response:\n");
ec_print_data(data, rec_size);
}
if (rec_size < 10) {
EC_SLAVE_ERR(slave, "Received currupted SDO upload"
" segment response!\n");

View File

@ -989,11 +989,12 @@ void ec_fsm_master_state_scan_slave(
master->scan_index = master->slave_count;
wake_up_interruptible(&master->scan_queue);
ec_master_calc_dc(master);
// Attach slave configurations
ec_master_attach_slave_configs(master);
// Calculate DC (needs attached slaves due to reference clock selection)
ec_master_calc_dc(master);
#ifdef EC_EOE
// check if EoE processing has to be started
ec_master_eoe_start(master);

View File

@ -61,6 +61,23 @@
rt_mutex_lock_interruptible(lock, 0)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 47)
#define smp_store_release(p, v) \
do { \
smp_mb(); \
ACCESS_ONCE(*p) = (v); \
} while (0)
#define smp_load_acquire(p) \
({ \
typeof(*p) ___p1 = ACCESS_ONCE(*p); \
smp_mb(); \
___p1; \
})
#endif
#include "master.h"
/****************************************************************************/
@ -195,6 +212,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
master->phase = EC_ORPHANED;
master->active = 0;
master->config_changed = 0;
master->injection_seq_fsm = 0;
master->injection_seq_rt = 0;
@ -1596,6 +1614,7 @@ static int ec_master_idle_thread(void *priv_data)
static int ec_master_operation_thread(void *priv_data)
{
ec_master_t *master = (ec_master_t *) priv_data;
unsigned int seq_rt;
EC_MASTER_DBG(master, 1, "Operation thread running"
" with fsm interval = %u us, max data size=%zu\n",
@ -1604,7 +1623,11 @@ static int ec_master_operation_thread(void *priv_data)
while (!kthread_should_stop()) {
ec_datagram_output_stats(&master->fsm_datagram);
if (master->injection_seq_rt == master->injection_seq_fsm) {
/* Use smp_load_acquire() to prevent re-ordering.
* https://gitlab.com/etherlab.org/ethercat/-/work_items/168 */
seq_rt = smp_load_acquire(&master->injection_seq_rt);
if (seq_rt == master->injection_seq_fsm) { // was injected
// output statistics
ec_master_output_stats(master);
@ -1616,7 +1639,9 @@ static int ec_master_operation_thread(void *priv_data)
if (ec_fsm_master_exec(&master->fsm)) {
// Inject datagrams (let the RT thread queue them, see
// ecrt_master_send())
master->injection_seq_fsm++;
// re-ordering-safe version of `master->injection_seq_fsm++`
smp_store_release(&master->injection_seq_fsm,
master->injection_seq_fsm + 1);
}
ec_master_exec_slave_fsms(master);
@ -2436,11 +2461,14 @@ int ecrt_master_send(ec_master_t *master)
{
ec_datagram_t *datagram, *n;
ec_device_index_t dev_idx;
unsigned int seq_fsm;
if (master->injection_seq_rt != master->injection_seq_fsm) {
seq_fsm = smp_load_acquire(&master->injection_seq_fsm);
if (master->injection_seq_rt != seq_fsm) {
// inject datagram produced by master FSM
ec_master_queue_datagram(master, &master->fsm_datagram);
master->injection_seq_rt = master->injection_seq_fsm;
smp_store_release(&master->injection_seq_rt, seq_fsm);
}
ec_master_inject_external_datagrams(master);

View File

@ -68,6 +68,8 @@ endif
# Any precious variable used inside script_templates should appear here
expand_script = $(SED) \
-e 's,[@]VERSION[@],$(VERSION),g' \
-e 's,[@]ipcmd[@],$(ipcmd),g' \
-e 's,[@]kmoddir[@],$(kmoddir),g' \
-e 's,[@]bindir[@],$(bindir),g' \
-e 's,[@]sbindir[@],$(sbindir),g' \
-e 's,[@]sysconfdir[@],$(sysconfdir),g'

View File

@ -25,13 +25,13 @@
#
#------------------------------------------------------------------------------
LSMOD=/sbin/lsmod
MODPROBE=/sbin/modprobe
RMMOD=/sbin/rmmod
MODINFO=/sbin/modinfo
IP=/bin/ip
LSMOD="@kmoddir@/lsmod"
MODPROBE="@kmoddir@/modprobe"
RMMOD="@kmoddir@/rmmod"
MODINFO="@kmoddir@/modinfo"
IP="@ipcmd@"
ETHERCAT=@bindir@/ethercat
ETHERCAT="@bindir@/ethercat"
#------------------------------------------------------------------------------
@ -39,7 +39,7 @@ if [ "$1" = "-c" ]; then
ETHERCAT_CONFIG="$2"
COMMAND="$3"
else
ETHERCAT_CONFIG=@sysconfdir@/ethercat.conf
ETHERCAT_CONFIG="@sysconfdir@/ethercat.conf"
COMMAND="$1"
fi

View File

@ -292,7 +292,11 @@ static int ec_tty_init(ec_tty_t *t, int minor,
static void ec_tty_clear(ec_tty_t *tty)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
timer_delete_sync(&tty->timer);
#else
del_timer_sync(&tty->timer);
#endif
tty_unregister_device(tty_driver, tty->minor);
}
@ -367,10 +371,14 @@ static void ec_tty_wakeup(struct timer_list *t)
static void ec_tty_wakeup(unsigned long data)
#endif
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
ec_tty_t *tty = timer_container_of(tty, t, timer);
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
ec_tty_t *tty = from_timer(tty, t, timer);
#else
ec_tty_t *tty = (ec_tty_t *) data;
#endif
#endif
size_t to_recv;