Improved EoE handling: Avoided skipping of datagrams and release lock
while processing.
This commit is contained in:
parent
7369f5a5a2
commit
1c829731ed
|
|
@ -99,6 +99,7 @@ int ec_eoe_init(
|
|||
eoe->slave = slave;
|
||||
|
||||
ec_datagram_init(&eoe->datagram);
|
||||
eoe->queue_datagram = 0;
|
||||
eoe->state = ec_eoe_state_rx_start;
|
||||
eoe->opened = 0;
|
||||
eoe->rx_skb = NULL;
|
||||
|
|
@ -283,7 +284,7 @@ int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
|
|||
(eoe->tx_frame_number & 0x0F) << 12));
|
||||
|
||||
memcpy(data + 4, eoe->tx_frame->skb->data + eoe->tx_offset, current_size);
|
||||
ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
|
||||
eoe->queue_datagram = 1;
|
||||
|
||||
eoe->tx_offset += current_size;
|
||||
eoe->tx_fragment_number++;
|
||||
|
|
@ -300,6 +301,10 @@ void ec_eoe_run(ec_eoe_t *eoe /**< EoE handler */)
|
|||
{
|
||||
if (!eoe->opened) return;
|
||||
|
||||
// if the datagram was not sent, or is not yet received, skip this cycle
|
||||
if (eoe->queue_datagram || eoe->datagram.state == EC_DATAGRAM_SENT)
|
||||
return;
|
||||
|
||||
// call state function
|
||||
eoe->state(eoe);
|
||||
|
||||
|
|
@ -311,11 +316,26 @@ void ec_eoe_run(ec_eoe_t *eoe /**< EoE handler */)
|
|||
eoe->tx_counter = 0;
|
||||
eoe->rate_jiffies = jiffies;
|
||||
}
|
||||
|
||||
ec_datagram_output_stats(&eoe->datagram);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Queues the datagram, if necessary.
|
||||
*/
|
||||
|
||||
void ec_eoe_queue(ec_eoe_t *eoe /**< EoE handler */)
|
||||
{
|
||||
if (eoe->queue_datagram) {
|
||||
ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
|
||||
eoe->queue_datagram = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Returns the state of the device.
|
||||
\return 1 if the device is "up", 0 if it is "down"
|
||||
|
|
@ -343,7 +363,7 @@ void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
|
|||
return;
|
||||
|
||||
ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
|
||||
ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
|
||||
eoe->queue_datagram = 1;
|
||||
eoe->state = ec_eoe_state_rx_check;
|
||||
}
|
||||
|
||||
|
|
@ -369,7 +389,7 @@ void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
|
|||
}
|
||||
|
||||
ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram);
|
||||
ec_master_queue_datagram(eoe->slave->master, &eoe->datagram);
|
||||
eoe->queue_datagram = 1;
|
||||
eoe->state = ec_eoe_state_rx_fetch;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ struct ec_eoe
|
|||
struct list_head list; /**< list item */
|
||||
ec_slave_t *slave; /**< pointer to the corresponding slave */
|
||||
ec_datagram_t datagram; /**< datagram */
|
||||
unsigned int queue_datagram; /**< the datagram is ready for queuing */
|
||||
void (*state)(ec_eoe_t *); /**< state function for the state machine */
|
||||
struct net_device *dev; /**< net_device for virtual ethernet device */
|
||||
struct net_device_stats stats; /**< device statistics */
|
||||
|
|
@ -102,6 +103,7 @@ struct ec_eoe
|
|||
int ec_eoe_init(ec_eoe_t *, ec_slave_t *);
|
||||
void ec_eoe_clear(ec_eoe_t *);
|
||||
void ec_eoe_run(ec_eoe_t *);
|
||||
void ec_eoe_queue(ec_eoe_t *);
|
||||
int ec_eoe_is_open(const ec_eoe_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -1162,7 +1162,6 @@ void ec_master_eoe_run(unsigned long data /**< master pointer */)
|
|||
cycles_t cycles_start, cycles_end;
|
||||
unsigned long restart_jiffies;
|
||||
|
||||
|
||||
list_for_each_entry(eoe, &master->eoe_handlers, list) {
|
||||
if (ec_eoe_is_open(eoe)) {
|
||||
none_open = 0;
|
||||
|
|
@ -1172,11 +1171,11 @@ void ec_master_eoe_run(unsigned long data /**< master pointer */)
|
|||
if (none_open)
|
||||
goto queue_timer;
|
||||
|
||||
if (master->request_cb(master->cb_data)) goto queue_timer;
|
||||
|
||||
// receive datagrams
|
||||
if (master->request_cb(master->cb_data)) goto queue_timer;
|
||||
cycles_start = get_cycles();
|
||||
ecrt_master_receive(master);
|
||||
master->release_cb(master->cb_data);
|
||||
|
||||
// actual EoE processing
|
||||
list_for_each_entry(eoe, &master->eoe_handlers, list) {
|
||||
|
|
@ -1184,10 +1183,15 @@ void ec_master_eoe_run(unsigned long data /**< master pointer */)
|
|||
}
|
||||
|
||||
// send datagrams
|
||||
if (master->request_cb(master->cb_data)) {
|
||||
goto queue_timer;
|
||||
}
|
||||
list_for_each_entry(eoe, &master->eoe_handlers, list) {
|
||||
ec_eoe_queue(eoe);
|
||||
}
|
||||
ecrt_master_send(master);
|
||||
cycles_end = get_cycles();
|
||||
|
||||
master->release_cb(master->cb_data);
|
||||
cycles_end = get_cycles();
|
||||
|
||||
master->eoe_cycle_times[master->eoe_cycle_time_pos]
|
||||
= (u32) (cycles_end - cycles_start) * 1000 / cpu_khz;
|
||||
|
|
@ -1197,7 +1201,7 @@ void ec_master_eoe_run(unsigned long data /**< master pointer */)
|
|||
queue_timer:
|
||||
restart_jiffies = HZ / EC_EOE_FREQUENCY;
|
||||
if (!restart_jiffies) restart_jiffies = 1;
|
||||
master->eoe_timer.expires += restart_jiffies;
|
||||
master->eoe_timer.expires = jiffies + restart_jiffies;
|
||||
add_timer(&master->eoe_timer);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue