diff -u -p linux/include/net/irda/timer.d7.h linux/include/net/irda/timer.h
--- linux/include/net/irda/timer.d7.h	Wed Nov 19 18:26:53 2003
+++ linux/include/net/irda/timer.h	Wed Nov 19 18:28:23 2003
@@ -38,14 +38,14 @@
 #include <net/irda/irda_device.h>
 
 /* 
- *  Timeout definitions, some defined in IrLAP p. 92
+ *  Timeout definitions, some defined in IrLAP 6.13.5 - p. 92
  */
 #define POLL_TIMEOUT        (450*HZ/1000)    /* Must never exceed 500 ms */
 #define FINAL_TIMEOUT       (500*HZ/1000)    /* Must never exceed 500 ms */
 
 /* 
- *  Normally twice of p-timer. Note 3, IrLAP p. 60 suggests at least twice 
- *  duration of the P-timer.
+ *  Normally twice of p-timer. Note 3, IrLAP 6.3.11.2 - p. 60 suggests
+ *  at least twice duration of the P-timer.
  */
 #define WD_TIMEOUT          (POLL_TIMEOUT*2)
 
diff -u -p linux/net/irda/irlap_event.d7.c linux/net/irda/irlap_event.c
--- linux/net/irda/irlap_event.d7.c	Wed Nov 19 18:27:45 2003
+++ linux/net/irda/irlap_event.c	Wed Nov 19 18:33:30 2003
@@ -923,6 +923,12 @@ static int irlap_state_setup(struct irla
 		/* This frame will actually be sent at the new speed */
 		irlap_send_rr_frame(self, CMD_FRAME);
 
+		/* The timer is set to half the normal timer to quickly
+		 * detect a failure to negociate the new connection
+		 * parameters. IrLAP 6.11.3.2, note 3.
+		 * Note that currently we don't process this failure
+		 * properly, as we should do a quick disconnect.
+		 * Jean II */
 		irlap_start_final_timer(self, self->final_timeout/2);
 		irlap_next_state(self, LAP_NRM_P);
 
@@ -1304,7 +1310,12 @@ static int irlap_state_nrm_p(struct irla
 				irlap_resend_rejected_frames(self, CMD_FRAME);
 				
 				self->ack_required = FALSE;
-				irlap_start_final_timer(self, self->final_timeout);
+
+				/* Make sure we account for the time
+				 * to transmit our frames. See comemnts
+				 * in irlap_send_data_primary_poll().
+				 * Jean II */
+				irlap_start_final_timer(self, 2 * self->final_timeout);
 				
 				/* Keep state, do not move this line */
 				irlap_next_state(self, LAP_NRM_P);
@@ -1343,8 +1354,9 @@ static int irlap_state_nrm_p(struct irla
 				/* Resend rejected frames */
 				irlap_resend_rejected_frames(self, CMD_FRAME);
 				
-				/* Give peer some time to retransmit! */
-				irlap_start_final_timer(self, self->final_timeout);
+				/* Give peer some time to retransmit! 
+				 * But account for our own Tx. */
+				irlap_start_final_timer(self, 2 * self->final_timeout);
 
 				/* Keep state, do not move this line */
 				irlap_next_state(self, LAP_NRM_P);
@@ -1441,6 +1453,8 @@ static int irlap_state_nrm_p(struct irla
 			/* Resend rejected frames */
 			irlap_resend_rejected_frames(self, CMD_FRAME);
 			
+			/* Final timer ??? Jean II */
+
 			irlap_next_state(self, LAP_NRM_P);
 		} else if (ret == NR_INVALID) {
 			IRDA_DEBUG(1, "%s(), Received RR with "
@@ -1532,7 +1546,7 @@ static int irlap_state_nrm_p(struct irla
 			irlap_send_rr_frame(self, CMD_FRAME);
 		} else
 			irlap_resend_rejected_frames(self, CMD_FRAME);
-		irlap_start_final_timer(self, self->final_timeout);
+		irlap_start_final_timer(self, 2 * self->final_timeout);
 		break;
 	case RECV_SREJ_RSP:
 		irlap_update_nr_received(self, info->nr);
@@ -1541,7 +1555,7 @@ static int irlap_state_nrm_p(struct irla
 			irlap_send_rr_frame(self, CMD_FRAME);
 		} else
 			irlap_resend_rejected_frame(self, CMD_FRAME);
-		irlap_start_final_timer(self, self->final_timeout);
+		irlap_start_final_timer(self, 2 * self->final_timeout);
 		break;
 	case RECV_RD_RSP:
 		IRDA_DEBUG(1, "%s(), RECV_RD_RSP\n", __FUNCTION__);
diff -u -p linux/net/irda/irlap_frame.d7.c linux/net/irda/irlap_frame.c
--- linux/net/irda/irlap_frame.d7.c	Wed Nov 19 18:27:54 2003
+++ linux/net/irda/irlap_frame.c	Wed Nov 19 18:34:24 2003
@@ -764,6 +764,7 @@ void irlap_send_data_primary(struct irla
 void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb) 
 {
 	struct sk_buff *tx_skb;
+	int transmission_time;
 
 	/* Stop P timer */
 	del_timer(&self->poll_timer);
@@ -812,13 +813,49 @@ void irlap_send_data_primary_poll(struct
 		}
 	}
 
+	/* How much time we took for transmission of all frames.
+	 * We don't know, so let assume we used the full window. Jean II */
+	transmission_time = self->final_timeout;
+
+	/* Reset parameter so that we can fill next window */
 	self->window = self->window_size;
+
 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
+	/* Remove what we have not used. Just do a prorata of the
+	 * bytes left in window to window capacity.
+	 * See max_line_capacities[][] in qos.c for details. Jean II */
+	transmission_time -= (self->final_timeout * self->bytes_left
+			      / self->line_capacity);
+	IRDA_DEBUG(4, "%s() adjusting transmission_time : ft=%d, bl=%d, lc=%d -> tt=%d\n", __FUNCTION__, self->final_timeout, self->bytes_left, self->line_capacity, transmission_time);
+
 	/* We are allowed to transmit a maximum number of bytes again. */
 	self->bytes_left = self->line_capacity;
 #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
 
-	irlap_start_final_timer(self, self->final_timeout);
+	/*
+	 * The network layer has a intermediate buffer between IrLAP
+	 * and the IrDA driver which can contain 8 frames. So, even
+	 * though IrLAP is currently sending the *last* frame of the
+	 * tx-window, the driver most likely has only just started
+	 * sending the *first* frame of the same tx-window.
+	 * I.e. we are always at the very begining of or Tx window.
+	 * Now, we are supposed to set the final timer from the end
+	 * of our tx-window to let the other peer reply. So, we need
+	 * to add extra time to compensate for the fact that we
+	 * are really at the start of tx-window, otherwise the final timer
+	 * might expire before he can answer...
+	 * Jean II
+	 */
+	irlap_start_final_timer(self, self->final_timeout + transmission_time);
+
+	/*
+	 * The clever amongst you might ask why we do this adjustement
+	 * only here, and not in all the other cases in irlap_event.c.
+	 * In all those other case, we only send a very short management
+	 * frame (few bytes), so the adjustement would be lost in the
+	 * noise...
+	 * The exception of course is irlap_resend_rejected_frame().
+	 * Jean II */
 }
 
 /*
@@ -980,7 +1017,7 @@ void irlap_resend_rejected_frames(struct
 	}
 #if 0 /* Not yet */
 	/* 
-	 *  We can now fill the window with additinal data frames
+	 *  We can now fill the window with additional data frames
 	 */
 	while (skb_queue_len( &self->txq) > 0) {
 		
