]> git.hungrycats.org Git - linux/commitdiff
[IRDA]: Proper calculation for F-timer. Improve interoperability.
authorJean Tourrilhes <jt@bougret.hpl.hp.com>
Thu, 8 Jan 2004 18:08:39 +0000 (10:08 -0800)
committerStephen Hemminger <shemminger@osdl.org>
Thu, 8 Jan 2004 18:08:39 +0000 (10:08 -0800)
include/net/irda/timer.h
net/irda/irlap_event.c
net/irda/irlap_frame.c

index 84d339480ddc090f3ffbce1a1bc592b197520b85..739a89d3750dea395b9bd30568549e87bb7ea673 100644 (file)
@@ -40,14 +40,14 @@ struct lsap_cb;
 struct lap_cb;
 
 /* 
- *  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)
 
index 16fbb21637acc33dc24ef40fbda530d01c75f0c0..005a96c9ed080abbec4feadd4ef65b323547c5c4 100644 (file)
@@ -932,6 +932,12 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event,
                /* 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);
 
@@ -1312,7 +1318,12 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
                                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);
@@ -1352,8 +1363,9 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
                                /* 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);
@@ -1450,6 +1462,8 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
                        /* 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 "
@@ -1541,7 +1555,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
                        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);
@@ -1550,7 +1564,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
                        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__);
index 97d2f1729b6cc5e80513079bb5a58458fb6a7610..388f4ea83e1ab01a2eddabb23d3b51f9111156d8 100644 (file)
@@ -779,6 +779,7 @@ void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb)
 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);
@@ -829,13 +830,49 @@ void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb)
                }
        }
 
+       /* 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 */
 }
 
 /*
@@ -1003,7 +1040,7 @@ void irlap_resend_rejected_frames(struct irlap_cb *self, int command)
        }
 #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) {