37 #include <linux/module.h> 38 #include <linux/skbuff.h> 39 #include <linux/if_ether.h> 40 #include <linux/netdevice.h> 41 #include <linux/jiffies.h> 47 #define timersub(a, b, result) \ 49 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ 50 (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ 51 if ((result)->tv_usec < 0) { \ 53 (result)->tv_usec += 1000000; \ 88 device->cycles_poll = 0;
91 device->timeval_poll.tv_sec = 0;
92 device->timeval_poll.tv_usec = 0;
99 for (i = 0; i < EC_DEBUG_RING_SIZE; i++) {
100 ec_debug_frame_t *df = &device->debug_frames[i];
109 device->debug_frame_index = 0;
110 device->debug_frame_count = 0;
121 sprintf(ifname,
"ecdbg%c%u", mb, master->
index);
131 if (!(device->
tx_skb[i] = dev_alloc_skb(ETH_FRAME_LEN))) {
132 EC_MASTER_ERR(master,
"Error allocating device socket buffer!\n");
138 skb_reserve(device->
tx_skb[i], ETH_HLEN);
139 eth = (
struct ethhdr *) skb_push(device->
tx_skb[i], ETH_HLEN);
140 eth->h_proto = htons(0x88A4);
141 memset(eth->h_dest, 0xFF, ETH_ALEN);
149 dev_kfree_skb(device->
tx_skb[i]);
173 dev_kfree_skb(device->
tx_skb[i]);
185 struct net_device *net_dev,
187 struct module *module
195 device->
dev = net_dev;
200 device->
tx_skb[i]->dev = net_dev;
201 eth = (
struct ethhdr *) (device->
tx_skb[i]->data);
202 memcpy(eth->h_source, net_dev->dev_addr, ETH_ALEN);
233 device->
tx_skb[i]->dev = NULL;
263 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) 264 ret = device->
dev->netdev_ops->ndo_open(device->
dev);
266 ret = device->
dev->open(device->
dev);
296 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) 297 ret = device->
dev->netdev_ops->ndo_stop(device->
dev);
299 ret = device->
dev->stop(device->
dev);
324 if (unlikely(reqd <= available)) {
336 t = device->timeval_poll;
338 pcaphdr->ts_sec = t.tv_sec;
339 pcaphdr->ts_usec = t.tv_usec;
340 pcaphdr->incl_len = size;
341 pcaphdr->orig_len = size;
345 memcpy(curr_data, data, size);
383 skb->len = ETH_HLEN + size;
391 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) 392 if (device->
dev->netdev_ops->ndo_start_xmit(skb, device->
dev) ==
395 if (device->
dev->hard_start_xmit(skb, device->
dev) == NETDEV_TX_OK)
400 device->
tx_bytes += ETH_HLEN + size;
407 ec_device_debug_ring_append(
408 device, TX, skb->data + ETH_HLEN, size);
444 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) 446 static void do_gettimeofday(
struct timeval *tv)
448 struct timespec64 ts;
451 tv->tv_sec = ts.tv_sec;
452 tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
462 void ec_device_debug_ring_append(
464 ec_debug_frame_dir_t dir,
469 ec_debug_frame_t *df = &device->debug_frames[device->debug_frame_index];
473 do_gettimeofday(&df->t);
476 df->t = device->timeval_poll;
478 memcpy(df->data, data, size);
479 df->data_size = size;
481 device->debug_frame_index++;
482 device->debug_frame_index %= EC_DEBUG_RING_SIZE;
483 if (unlikely(device->debug_frame_count < EC_DEBUG_RING_SIZE))
484 device->debug_frame_count++;
491 void ec_device_debug_ring_print(
496 unsigned int ring_index;
497 const ec_debug_frame_t *df;
501 ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE - 1)
502 % EC_DEBUG_RING_SIZE;
503 t0 = device->debug_frames[ring_index].t;
508 ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE
509 - device->debug_frame_count) % EC_DEBUG_RING_SIZE;
511 for (i = 0; i < device->debug_frame_count; i++) {
512 df = &device->debug_frames[ring_index];
513 timersub(&t0, &df->t, &diff);
516 i + 1 - device->debug_frame_count,
517 (
unsigned int) diff.tv_sec,
518 (
unsigned int) diff.tv_usec,
519 (df->dir == TX) ?
"TX" :
"RX");
523 ring_index %= EC_DEBUG_RING_SIZE;
540 #ifdef EC_HAVE_CYCLES 541 device->cycles_poll = get_cycles();
545 do_gettimeofday(&device->timeval_poll);
546 #elif !defined(EC_RTDM) 548 do_gettimeofday(&device->timeval_poll);
607 char dev_str[20], mac_str[20];
612 sprintf(dev_str,
"main");
614 sprintf(dev_str,
"backup");
618 sprintf(dev_str,
"UNKNOWN");
621 EC_MASTER_INFO(master,
"Releasing %s device %s.\n", dev_str, mac_str);
639 unsigned int all_open = 1, dev_idx;
703 const void *ec_data = data + ETH_HLEN;
704 size_t ec_size = size - ETH_HLEN;
706 if (unlikely(!data)) {
727 ec_device_debug_ring_append(device, RX, ec_data, ec_size);
747 if (unlikely(!device)) {
748 EC_WARN(
"ecdev_set_link() called with null device!\n");
755 "Link state of %s changed to %s.\n",
756 device->
dev->name, (state ?
"UP" :
"DOWN"));
772 if (unlikely(!device)) {
773 EC_WARN(
"ecdev_get_link() called with null device!\n");
#define EC_WARN(fmt, args...)
Convenience macro for printing EtherCAT-specific warnings to syslog.
struct sk_buff * tx_skb[EC_TX_RING_SIZE]
transmit skb ring
void * pcap_curr_data
pcap debug output current memory pointer
u64 tx_count
Number of frames sent.
const unsigned int rate_intervals[]
List of intervals for statistics [s].
void ecdev_close(ec_device_t *device)
Makes the master leave IDLE phase and closes the network device.
ec_pollfunc_t poll
pointer to the device's poll function
void ec_debug_clear(ec_debug_t *dbg)
Debug interface destructor.
unsigned long jiffies_poll
jiffies of last poll
void * pcap_data
pcap debug output memory pointer
u64 last_tx_count
Number of frames sent of last statistics cycle.
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
int ecdev_open(ec_device_t *device)
Opens the network device and makes the master enter IDLE phase.
struct module * module
pointer to the device's owning module
void ec_device_clear(ec_device_t *device)
Destructor.
int ec_device_open(ec_device_t *device)
Opens the EtherCAT device.
static void pcap_record(ec_device_t *device, const void *data, size_t size)
Records a packet in the master's pcap buffer, if there is room.
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
void ec_device_update_stats(ec_device_t *device)
Update device statistics.
uint8_t link_state
device link state
u64 rx_count
Number of frames received.
u64 last_tx_bytes
Number of bytes sent of last statistics cycle.
int ec_master_enter_idle_phase(ec_master_t *master)
Transition function from ORPHANED to IDLE phase.
size_t ec_mac_print(const uint8_t *, char *)
Print a MAC address to a buffer.
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
EtherCAT master structure.
void ec_debug_unregister(ec_debug_t *dbg)
Unregister debug interface.
void ec_device_send(ec_device_t *device, size_t size)
Sends the content of the transmit socket buffer.
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
ec_lock_t device_sem
Device semaphore.
#define EC_TX_RING_SIZE
Size of the transmit ring.
ec_device_stats_t device_stats
Device statistics.
u64 last_rx_count
Number of frames received of last statistics cycle.
ec_master_phase_t phase
Master phase.
void(* ec_pollfunc_t)(struct net_device *)
Device poll function type.
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
unsigned int tx_ring_index
last ring entry used to transmit
unsigned int debug_level
Master debug level.
void ec_master_leave_idle_phase(ec_master_t *master)
Transition function from IDLE to ORPHANED phase.
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
int ec_device_init(ec_device_t *device, ec_master_t *master)
Constructor.
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
ec_master_t * master
EtherCAT master.
u64 rx_bytes
Number of bytes received.
u64 tx_count
Number of frames sent.
uint8_t ecdev_get_link(const ec_device_t *device)
Reads the link state.
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
void ec_debug_send(ec_debug_t *dbg, const uint8_t *data, size_t size)
Sends frame data to the interface.
void ec_debug_register(ec_debug_t *dbg, const struct net_device *net_dev)
Register debug interface.
int ec_debug_init(ec_debug_t *dbg, ec_device_t *device, const char *name)
Debug interface constructor.
uint8_t * ec_device_tx_data(ec_device_t *device)
Returns a pointer to the device's transmit memory.
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
uint8_t open
true, if the net_device has been opened
u64 tx_errors
Number of transmit errors.
u64 last_rx_bytes
Number of bytes received of last statistics cycle.
u64 tx_bytes
Number of bytes sent.
void ecdev_receive(ec_device_t *device, const void *data, size_t size)
Accepts a received frame.
int ec_device_close(ec_device_t *device)
Stops the EtherCAT device.
u64 rx_count
Number of frames received.
void ecdev_set_link(ec_device_t *device, uint8_t state)
Sets a new link state.
void ec_device_attach(ec_device_t *device, struct net_device *net_dev, ec_pollfunc_t poll, struct module *module)
Associate with net_device.
void ec_device_detach(ec_device_t *device)
Disconnect from net_device.
EtherCAT device structure.
unsigned long pcap_size
Pcap buffer size in bytes.
struct net_device * dev
pointer to the assigned net_device
void ec_device_poll(ec_device_t *device)
Calls the poll function of the assigned net_device.
void ecdev_withdraw(ec_device_t *device)
Withdraws an EtherCAT device from the master.
u64 rx_bytes
Number of bytes received.
#define EC_MASTER_INFO(master, fmt, args...)
Convenience macro for printing master-specific information to syslog.
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.
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
u64 tx_bytes
Number of bytes sent.
void ec_device_clear_stats(ec_device_t *device)
Clears the frame statistics.
#define EC_MAX_DATA_SIZE
Resulting maximum data size of a single datagram in a frame.