/** EoE state: SET IP CHECK. */ void ec_fsm_eoe_set_ip_check( ec_fsm_eoe_t *fsm, /**< finite state machine */ ec_datagram_t *datagram /**< Datagram to use. */ ) { ec_slave_t *slave = fsm->slave; if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { ec_slave_mbox_prepare_check(slave, datagram); // can not fail. return; } if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_eoe_error; EC_SLAVE_ERR(slave, "Failed to receive EoE mailbox check datagram: "); ec_datagram_print_state(fsm->datagram); return; } if (fsm->datagram->working_counter != 1) { fsm->state = ec_fsm_eoe_error; EC_SLAVE_ERR(slave, "Reception of EoE mailbox check" " datagram failed: "); ec_datagram_print_wc_error(fsm->datagram); return; } if (!ec_slave_mbox_check(fsm->datagram)) { unsigned long diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; if (diff_ms >= EC_EOE_RESPONSE_TIMEOUT) { fsm->state = ec_fsm_eoe_error; EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for" " set IP parameter response.\n", diff_ms); return; } ec_slave_mbox_prepare_check(slave, datagram); // can not fail. fsm->retries = EC_FSM_RETRIES; return; } // fetch response ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_eoe_set_ip_response; }
/** State: RRQ SENT. * * Checks is the previous transmit datagram succeeded and sends the next * fragment, if necessary. */ void ec_fsm_foe_state_rrq_sent( ec_fsm_foe_t *fsm, /**< FoE statemachine. */ ec_datagram_t *datagram /**< Datagram to use. */ ) { ec_slave_t *slave = fsm->slave; #ifdef DEBUG_FOE EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); #endif if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: "); ec_datagram_print_state(fsm->datagram); return; } if (fsm->datagram->working_counter != 1) { // slave did not put anything in the mailbox yet ec_foe_set_rx_error(fsm, FOE_WC_ERROR); EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: "); ec_datagram_print_wc_error(fsm->datagram); return; } fsm->jiffies_start = fsm->datagram->jiffies_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail. fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_foe_state_data_check; }
/** State: WRQ SENT. * * Checks is the previous transmit datagram succeded and sends the next * fragment, if necessary. */ void ec_fsm_foe_state_data_sent( ec_fsm_foe_t *fsm, /**< Foe statemachine. */ ec_datagram_t *datagram /**< Datagram to use. */ ) { ec_slave_t *slave = fsm->slave; #ifdef DEBUG_FOE EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); #endif if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR); EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: "); ec_datagram_print_state(fsm->datagram); return; } if (fsm->datagram->working_counter != 1) { ec_foe_set_tx_error(fsm, FOE_WC_ERROR); EC_SLAVE_ERR(slave, "Reception of FoE data send failed: "); ec_datagram_print_wc_error(fsm->datagram); return; } ec_slave_mbox_prepare_check(slave, datagram); fsm->jiffies_start = jiffies; fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_foe_state_ack_check; }
/** EoE state: SET IP REQUEST. */ void ec_fsm_eoe_set_ip_request( ec_fsm_eoe_t *fsm, /**< finite state machine */ ec_datagram_t *datagram /**< Datagram to use. */ ) { ec_slave_t *slave = fsm->slave; if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { if (ec_fsm_eoe_prepare_set(fsm, datagram)) { fsm->state = ec_fsm_eoe_error; } return; } if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { fsm->state = ec_fsm_eoe_error; EC_SLAVE_ERR(slave, "Failed to receive EoE set IP parameter" " request: "); ec_datagram_print_state(fsm->datagram); return; } if (fsm->datagram->working_counter != 1) { unsigned long diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ; if (!fsm->datagram->working_counter) { if (diff_ms < EC_EOE_RESPONSE_TIMEOUT) { // no response; send request datagram again if (ec_fsm_eoe_prepare_set(fsm, datagram)) { fsm->state = ec_fsm_eoe_error; } return; } } fsm->state = ec_fsm_eoe_error; EC_SLAVE_ERR(slave, "Reception of EoE set IP parameter request" " failed after %lu ms: ", diff_ms); ec_datagram_print_wc_error(fsm->datagram); return; } fsm->jiffies_start = fsm->datagram->jiffies_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail. fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_eoe_set_ip_check; }
/** Check for acknowledge. */ void ec_fsm_foe_state_ack_check( ec_fsm_foe_t *fsm, /**< FoE statemachine. */ ec_datagram_t *datagram /**< Datagram to use. */ ) { ec_slave_t *slave = fsm->slave; #ifdef DEBUG_FOE EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); #endif if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: "); ec_datagram_print_state(fsm->datagram); return; } if (fsm->datagram->working_counter != 1) { ec_foe_set_rx_error(fsm, FOE_WC_ERROR); EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram" " failed: "); ec_datagram_print_wc_error(fsm->datagram); return; } if (!ec_slave_mbox_check(fsm->datagram)) { // slave did not put anything in the mailbox yet unsigned long diff_ms = (fsm->datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; if (diff_ms >= EC_FSM_FOE_TIMEOUT) { ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR); EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n"); return; } ec_slave_mbox_prepare_check(slave, datagram); // can not fail. fsm->retries = EC_FSM_RETRIES; return; } // Fetch response ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_foe_state_ack_read; }
/** Sent an acknowledge. */ void ec_fsm_foe_state_sent_ack( ec_fsm_foe_t *fsm, /**< FoE statemachine. */ ec_datagram_t *datagram /**< Datagram to use. */ ) { ec_slave_t *slave = fsm->slave; #ifdef DEBUG_FOE EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); #endif if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); EC_SLAVE_ERR(slave, "Failed to send FoE ACK: "); ec_datagram_print_state(fsm->datagram); return; } if (fsm->datagram->working_counter != 1) { // slave did not put anything into the mailbox yet ec_foe_set_rx_error(fsm, FOE_WC_ERROR); EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: "); ec_datagram_print_wc_error(fsm->datagram); return; } fsm->jiffies_start = fsm->datagram->jiffies_sent; ec_slave_mbox_prepare_check(slave, datagram); // can not fail. if (fsm->rx_last_packet) { fsm->rx_expected_packet_no = 0; fsm->request->data_size = fsm->rx_buffer_offset; fsm->state = ec_fsm_foe_end; } else { fsm->rx_expected_packet_no++; fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_foe_state_data_check; } }