summaryrefslogtreecommitdiffstats
path: root/src/net/aoe.c
diff options
context:
space:
mode:
authorMichael Brown2006-06-01 16:33:52 +0200
committerMichael Brown2006-06-01 16:33:52 +0200
commit48fb6c6dc2f75e57b79eaeb2e63790e315529f7f (patch)
treeaf45c48f86e57ba05fba9f9b6ba964f0557d461e /src/net/aoe.c
parentMake DBG_DISCARD correct (diff)
downloadipxe-48fb6c6dc2f75e57b79eaeb2e63790e315529f7f.tar.gz
ipxe-48fb6c6dc2f75e57b79eaeb2e63790e315529f7f.tar.xz
ipxe-48fb6c6dc2f75e57b79eaeb2e63790e315529f7f.zip
Updated retry timer mechanism to incorporate smoothed RTT estimation.
AoE now uses the retry timer mechanism.
Diffstat (limited to 'src/net/aoe.c')
-rw-r--r--src/net/aoe.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/net/aoe.c b/src/net/aoe.c
index 198bbb55..1e9eb321 100644
--- a/src/net/aoe.c
+++ b/src/net/aoe.c
@@ -115,10 +115,28 @@ static int aoe_send_command ( struct aoe_session *aoe ) {
aoe->command_offset, data_out_len );
/* Send packet */
+ start_timer ( &aoe->timer );
return net_transmit_via ( pkb, aoe->netdev );
}
/**
+ * Handle AoE retry timer expiry
+ *
+ * @v timer AoE retry timer
+ * @v fail Failure indicator
+ */
+static void aoe_timer_expired ( struct retry_timer *timer, int fail ) {
+ struct aoe_session *aoe =
+ container_of ( timer, struct aoe_session, timer );
+
+ if ( fail ) {
+ aoe_done ( aoe, -ETIMEDOUT );
+ } else {
+ aoe_send_command ( aoe );
+ }
+}
+
+/**
* Handle AoE response
*
* @v aoe AoE session
@@ -134,10 +152,18 @@ static int aoe_rx_response ( struct aoe_session *aoe, struct aoehdr *aoehdr,
unsigned int data_len;
/* Sanity check */
- if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoecmd ) ) )
+ if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoecmd ) ) ) {
+ /* Ignore packet; allow timer to trigger retransmit */
return -EINVAL;
+ }
rx_data_len = ( len - sizeof ( *aoehdr ) - sizeof ( *aoecmd ) );
+ /* Stop retry timer. After this point, every code path must
+ * either terminate the AoE operation via aoe_done(), or
+ * transmit a new packet.
+ */
+ stop_timer ( &aoe->timer );
+
/* Check for fatal errors */
if ( aoehdr->ver_flags & AOE_FL_ERROR ) {
aoe_done ( aoe, -EIO );
@@ -268,6 +294,7 @@ NET_PROTOCOL ( aoe_protocol );
*/
void aoe_open ( struct aoe_session *aoe ) {
memset ( aoe->target, 0xff, sizeof ( aoe->target ) );
+ aoe->timer.expired = aoe_timer_expired;
list_add ( &aoe->list, &aoe_sessions );
}