import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / net / irda / qos.c
1 /*********************************************************************
2  *                                
3  * Filename:      qos.c
4  * Version:       1.0
5  * Description:   IrLAP QoS parameter negotiation
6  * Status:        Stable
7  * Author:        Dag Brattli <dagb@cs.uit.no>
8  * Created at:    Tue Sep  9 00:00:26 1997
9  * Modified at:   Sun Jan 30 14:29:16 2000
10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
11  * 
12  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
13  *     All Rights Reserved.
14  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
15  *     
16  *     This program is free software; you can redistribute it and/or 
17  *     modify it under the terms of the GNU General Public License as 
18  *     published by the Free Software Foundation; either version 2 of 
19  *     the License, or (at your option) any later version.
20  * 
21  *     This program is distributed in the hope that it will be useful,
22  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  *     GNU General Public License for more details.
25  * 
26  *     You should have received a copy of the GNU General Public License 
27  *     along with this program; if not, write to the Free Software 
28  *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
29  *     MA 02111-1307 USA
30  *     
31  ********************************************************************/
32
33 #include <linux/config.h>
34 #include <asm/byteorder.h>
35
36 #include <net/irda/irda.h>
37 #include <net/irda/parameters.h>
38 #include <net/irda/qos.h>
39 #include <net/irda/irlap.h>
40
41 /*
42  * Maximum values of the baud rate we negociate with the other end.
43  * Most often, you don't have to change that, because Linux-IrDA will
44  * use the maximum offered by the link layer, which usually works fine.
45  * In some very rare cases, you may want to limit it to lower speeds...
46  */
47 int sysctl_max_baud_rate = 16000000;
48 /*
49  * Maximum value of the lap disconnect timer we negociate with the other end.
50  * Most often, the value below represent the best compromise, but some user
51  * may want to keep the LAP alive longuer or shorter in case of link failure.
52  * Remember that the threshold time (early warning) is fixed to 3s...
53  */
54 int sysctl_max_noreply_time = 12;
55 /*
56  * Minimum turn time to be applied before transmitting to the peer.
57  * Nonzero values (usec) are used as lower limit to the per-connection
58  * mtt value which was announced by the other end during negotiation.
59  * Might be helpful if the peer device provides too short mtt.
60  * Default is 10us which means using the unmodified value given by the
61  * peer except if it's 0 (0 is likely a bug in the other stack).
62  */
63 unsigned sysctl_min_tx_turn_time = 10;
64 /*
65  * Maximum data size to be used in transmission in payload of LAP frame.
66  * There is a bit of confusion in the IrDA spec :
67  * The LAP spec defines the payload of a LAP frame (I field) to be
68  * 2048 bytes max (IrLAP 1.1, chapt 6.6.5, p40).
69  * On the other hand, the PHY mention frames of 2048 bytes max (IrPHY
70  * 1.2, chapt 5.3.2.1, p41). But, this number includes the LAP header
71  * (2 bytes), and CRC (32 bits at 4 Mb/s). So, for the I field (LAP
72  * payload), that's only 2042 bytes. Oups !
73  * I've had trouble trouble transmitting 2048 bytes frames with USB
74  * dongles and nsc-ircc at 4 Mb/s, so adjust to 2042... I don't know
75  * if this bug applies only for 2048 bytes frames or all negociated
76  * frame sizes, but all hardware seem to support "2048 bytes" frames.
77  * You can use the sysctl to play with this value anyway.
78  * Jean II */
79 unsigned sysctl_max_tx_data_size = 2042;
80
81 static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get);
82 static int irlap_param_link_disconnect(void *instance, irda_param_t *parm, 
83                                        int get);
84 static int irlap_param_max_turn_time(void *instance, irda_param_t *param, 
85                                      int get);
86 static int irlap_param_data_size(void *instance, irda_param_t *param, int get);
87 static int irlap_param_window_size(void *instance, irda_param_t *param, 
88                                    int get);
89 static int irlap_param_additional_bofs(void *instance, irda_param_t *parm, 
90                                        int get);
91 static int irlap_param_min_turn_time(void *instance, irda_param_t *param, 
92                                      int get);
93
94 __u32 min_turn_times[]  = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
95 __u32 baud_rates[]      = { 2400, 9600, 19200, 38400, 57600, 115200, 576000, 
96                             1152000, 4000000, 16000000 };           /* bps */
97 __u32 data_sizes[]      = { 64, 128, 256, 512, 1024, 2048 };        /* bytes */
98 __u32 add_bofs[]        = { 48, 24, 12, 5, 3, 2, 1, 0 };            /* bytes */
99 __u32 max_turn_times[]  = { 500, 250, 100, 50 };                    /* ms */
100 __u32 link_disc_times[] = { 3, 8, 12, 16, 20, 25, 30, 40 };         /* secs */
101
102 __u32 max_line_capacities[10][4] = {
103        /* 500 ms     250 ms  100 ms  50 ms (max turn time) */
104         {    100,      0,      0,     0 }, /*     2400 bps */
105         {    400,      0,      0,     0 }, /*     9600 bps */
106         {    800,      0,      0,     0 }, /*    19200 bps */
107         {   1600,      0,      0,     0 }, /*    38400 bps */
108         {   2360,      0,      0,     0 }, /*    57600 bps */
109         {   4800,   2400,    960,   480 }, /*   115200 bps */
110         {  28800,  11520,   5760,  2880 }, /*   576000 bps */
111         {  57600,  28800,  11520,  5760 }, /*  1152000 bps */
112         { 200000, 100000,  40000, 20000 }, /*  4000000 bps */
113         { 800000, 400000, 160000, 80000 }, /* 16000000 bps */
114 };
115
116 static pi_minor_info_t pi_minor_call_table_type_0[] = {
117         { NULL, 0 },
118 /* 01 */{ irlap_param_baud_rate,       PV_INTEGER | PV_LITTLE_ENDIAN },
119         { NULL, 0 },
120         { NULL, 0 },
121         { NULL, 0 },
122         { NULL, 0 },
123         { NULL, 0 },
124         { NULL, 0 },
125 /* 08 */{ irlap_param_link_disconnect, PV_INT_8_BITS }
126 };
127
128 static pi_minor_info_t pi_minor_call_table_type_1[] = {
129         { NULL, 0 },
130         { NULL, 0 },
131 /* 82 */{ irlap_param_max_turn_time,   PV_INT_8_BITS },
132 /* 83 */{ irlap_param_data_size,       PV_INT_8_BITS },
133 /* 84 */{ irlap_param_window_size,     PV_INT_8_BITS },
134 /* 85 */{ irlap_param_additional_bofs, PV_INT_8_BITS },
135 /* 86 */{ irlap_param_min_turn_time,   PV_INT_8_BITS },
136 };
137
138 static pi_major_info_t pi_major_call_table[] = {
139         { pi_minor_call_table_type_0, 9 },
140         { pi_minor_call_table_type_1, 7 },
141 };
142
143 static pi_param_info_t irlap_param_info = { pi_major_call_table, 2, 0x7f, 7 };
144
145 /* ---------------------- LOCAL SUBROUTINES ---------------------- */
146 /* Note : we start with a bunch of local subroutines.
147  * As the compiler is "one pass", this is the only way to get them to
148  * inline properly...
149  * Jean II
150  */
151 /*
152  * Function value_index (value, array, size)
153  *
154  *    Returns the index to the value in the specified array
155  */
156 static inline int value_index(__u32 value, __u32 *array, int size)
157 {
158         int i;
159         
160         for (i=0; i < size; i++)
161                 if (array[i] == value)
162                         break;
163         return i;
164 }
165
166 /*
167  * Function index_value (index, array)
168  *
169  *    Returns value to index in array, easy!
170  *
171  */
172 static inline __u32 index_value(int index, __u32 *array) 
173 {
174         return array[index];
175 }
176
177 /*
178  * Function msb_index (word)
179  *
180  *    Returns index to most significant bit (MSB) in word
181  *
182  */
183 int msb_index (__u16 word) 
184 {
185         __u16 msb = 0x8000;
186         int index = 15;   /* Current MSB */
187         
188         while (msb) {
189                 if (word & msb)
190                         break;   /* Found it! */
191                 msb >>=1;
192                 index--;
193         }
194         return index;
195 }
196
197 static inline __u32 byte_value(__u8 byte, __u32 *array) 
198 {
199         int index;
200
201         ASSERT(array != NULL, return -1;);
202
203         index = msb_index(byte);
204
205         return index_value(index, array);
206 }
207
208 /*
209  * Function value_lower_bits (value, array)
210  *
211  *    Returns a bit field marking all possibility lower than value.
212  */
213 static inline int value_lower_bits(__u32 value, __u32 *array, int size, __u16 *field)
214 {
215         int     i;
216         __u16   mask = 0x1;
217         __u16   result = 0x0;
218
219         for (i=0; i < size; i++) {
220                 /* Add the current value to the bit field, shift mask */
221                 result |= mask;
222                 mask <<= 1;
223                 /* Finished ? */
224                 if (array[i] >= value)
225                         break;
226         }
227         /* Send back a valid index */
228         if(i >= size)
229           i = size - 1; /* Last item */
230         *field = result;
231         return i;
232 }
233
234 /*
235  * Function value_highest_bit (value, array)
236  *
237  *    Returns a bit field marking the highest possibility lower than value.
238  */
239 static inline int value_highest_bit(__u32 value, __u32 *array, int size, __u16 *field)
240 {
241         int     i;
242         __u16   mask = 0x1;
243         __u16   result = 0x0;
244
245         for (i=0; i < size; i++) {
246                 /* Finished ? */
247                 if (array[i] <= value)
248                         break;
249                 /* Shift mask */
250                 mask <<= 1;
251         }
252         /* Set the current value to the bit field */
253         result |= mask;
254         /* Send back a valid index */
255         if(i >= size)
256           i = size - 1; /* Last item */
257         *field = result;
258         return i;
259 }
260
261 /* -------------------------- MAIN CALLS -------------------------- */
262
263 /*
264  * Function irda_qos_compute_intersection (qos, new)
265  *
266  *    Compute the intersection of the old QoS capabilites with new ones
267  *
268  */
269 void irda_qos_compute_intersection(struct qos_info *qos, struct qos_info *new)
270 {
271         ASSERT(qos != NULL, return;);
272         ASSERT(new != NULL, return;);
273
274         /* Apply */
275         qos->baud_rate.bits       &= new->baud_rate.bits;
276         qos->window_size.bits     &= new->window_size.bits;
277         qos->min_turn_time.bits   &= new->min_turn_time.bits;
278         qos->max_turn_time.bits   &= new->max_turn_time.bits;
279         qos->data_size.bits       &= new->data_size.bits;
280         qos->link_disc_time.bits  &= new->link_disc_time.bits;
281         qos->additional_bofs.bits &= new->additional_bofs.bits;
282
283         irda_qos_bits_to_value(qos);
284 }
285
286 /*
287  * Function irda_init_max_qos_capabilies (qos)
288  *
289  *    The purpose of this function is for layers and drivers to be able to
290  *    set the maximum QoS possible and then "and in" their own limitations
291  * 
292  */
293 void irda_init_max_qos_capabilies(struct qos_info *qos)
294 {
295         int i;
296         /* 
297          *  These are the maximum supported values as specified on pages
298          *  39-43 in IrLAP
299          */
300
301         /* Use sysctl to set some configurable values... */
302         /* Set configured max speed */
303         i = value_lower_bits(sysctl_max_baud_rate, baud_rates, 10,
304                              &qos->baud_rate.bits);
305         sysctl_max_baud_rate = index_value(i, baud_rates);
306
307         /* Set configured max disc time */
308         i = value_lower_bits(sysctl_max_noreply_time, link_disc_times, 8,
309                              &qos->link_disc_time.bits);
310         sysctl_max_noreply_time = index_value(i, link_disc_times);
311
312         /* LSB is first byte, MSB is second byte */
313         qos->baud_rate.bits    &= 0x03ff;
314
315         qos->window_size.bits     = 0x7f;
316         qos->min_turn_time.bits   = 0xff;
317         qos->max_turn_time.bits   = 0x0f;
318         qos->data_size.bits       = 0x3f;
319         qos->link_disc_time.bits &= 0xff;
320         qos->additional_bofs.bits = 0xff;
321 }
322
323 /*
324  * Function irlap_adjust_qos_settings (qos)
325  *
326  *     Adjust QoS settings in case some values are not possible to use because
327  *     of other settings
328  */
329 void irlap_adjust_qos_settings(struct qos_info *qos)
330 {
331         __u32 line_capacity;
332         int index;
333
334         IRDA_DEBUG(2, __FUNCTION__ "()\n");
335
336         /*
337          * Make sure the mintt is sensible.
338          */
339         if (sysctl_min_tx_turn_time > qos->min_turn_time.value) {
340                 int i;
341
342                 /* We don't really need bits, but easier this way */
343                 i = value_highest_bit(sysctl_min_tx_turn_time, min_turn_times,
344                                       8, &qos->min_turn_time.bits);
345                 sysctl_min_tx_turn_time = index_value(i, min_turn_times);
346                 qos->min_turn_time.value = sysctl_min_tx_turn_time;
347         }
348
349         /* 
350          * Not allowed to use a max turn time less than 500 ms if the baudrate
351          * is less than 115200
352          */
353         if ((qos->baud_rate.value < 115200) && 
354             (qos->max_turn_time.value < 500))
355         {
356                 IRDA_DEBUG(0, __FUNCTION__ 
357                            "(), adjusting max turn time from %d to 500 ms\n",
358                            qos->max_turn_time.value);
359                 qos->max_turn_time.value = 500;
360         }
361         
362         /*
363          * The data size must be adjusted according to the baud rate and max 
364          * turn time
365          */
366         index = value_index(qos->data_size.value, data_sizes, 6);
367         line_capacity = irlap_max_line_capacity(qos->baud_rate.value, 
368                                                 qos->max_turn_time.value);
369
370 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
371         while ((qos->data_size.value > line_capacity) && (index > 0)) {
372                 qos->data_size.value = data_sizes[index--];
373                 IRDA_DEBUG(2, __FUNCTION__ 
374                            "(), reducing data size to %d\n",
375                            qos->data_size.value);
376         }
377 #else /* Use method described in section 6.6.11 of IrLAP */
378         while (irlap_requested_line_capacity(qos) > line_capacity) {
379                 ASSERT(index != 0, return;);
380
381                 /* Must be able to send at least one frame */
382                 if (qos->window_size.value > 1) {
383                         qos->window_size.value--;
384                         IRDA_DEBUG(2, __FUNCTION__ 
385                                    "(), reducing window size to %d\n",
386                                    qos->window_size.value);
387                 } else if (index > 1) {
388                         qos->data_size.value = data_sizes[index--];
389                         IRDA_DEBUG(2, __FUNCTION__ 
390                                    "(), reducing data size to %d\n",
391                                    qos->data_size.value);
392                 } else {
393                         WARNING(__FUNCTION__ "(), nothing more we can do!\n");
394                 }
395         }
396 #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
397         /*
398          * Fix tx data size according to user limits - Jean II
399          */
400         if (qos->data_size.value > sysctl_max_tx_data_size)
401                 /* Allow non discrete adjustement to avoid loosing capacity */
402                 qos->data_size.value = sysctl_max_tx_data_size;
403 }
404
405 /*
406  * Function irlap_negotiate (qos_device, qos_session, skb)
407  *
408  *    Negotiate QoS values, not really that much negotiation :-)
409  *    We just set the QoS capabilities for the peer station
410  *
411  */
412 int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb) 
413 {
414         int ret;
415         
416         ret = irda_param_extract_all(self, skb->data, skb->len, 
417                                      &irlap_param_info);
418         
419         /* Convert the negotiated bits to values */
420         irda_qos_bits_to_value(&self->qos_tx);
421         irda_qos_bits_to_value(&self->qos_rx);
422
423         irlap_adjust_qos_settings(&self->qos_tx);
424
425         IRDA_DEBUG(2, "Setting BAUD_RATE to %d bps.\n", 
426                    self->qos_tx.baud_rate.value);
427         IRDA_DEBUG(2, "Setting DATA_SIZE to %d bytes\n",
428                    self->qos_tx.data_size.value);
429         IRDA_DEBUG(2, "Setting WINDOW_SIZE to %d\n", 
430                    self->qos_tx.window_size.value);
431         IRDA_DEBUG(2, "Setting XBOFS to %d\n", 
432                    self->qos_tx.additional_bofs.value);
433         IRDA_DEBUG(2, "Setting MAX_TURN_TIME to %d ms.\n",
434                    self->qos_tx.max_turn_time.value);
435         IRDA_DEBUG(2, "Setting MIN_TURN_TIME to %d usecs.\n",
436                    self->qos_tx.min_turn_time.value);
437         IRDA_DEBUG(2, "Setting LINK_DISC to %d secs.\n", 
438                    self->qos_tx.link_disc_time.value);
439         return ret;
440 }
441
442 /*
443  * Function irlap_insert_negotiation_params (qos, fp)
444  *
445  *    Insert QoS negotiaion pararameters into frame
446  *
447  */
448 int irlap_insert_qos_negotiation_params(struct irlap_cb *self, 
449                                         struct sk_buff *skb)
450 {
451         int ret;
452
453         /* Insert data rate */
454         ret = irda_param_insert(self, PI_BAUD_RATE, skb->tail, 
455                                 skb_tailroom(skb), &irlap_param_info);
456         if (ret < 0)
457                 return ret;
458         skb_put(skb, ret);
459
460         /* Insert max turnaround time */
461         ret = irda_param_insert(self, PI_MAX_TURN_TIME, skb->tail, 
462                                 skb_tailroom(skb), &irlap_param_info);
463         if (ret < 0)
464                 return ret;
465         skb_put(skb, ret);
466
467         /* Insert data size */
468         ret = irda_param_insert(self, PI_DATA_SIZE, skb->tail, 
469                                 skb_tailroom(skb), &irlap_param_info);
470         if (ret < 0)
471                 return ret;
472         skb_put(skb, ret);
473
474         /* Insert window size */
475         ret = irda_param_insert(self, PI_WINDOW_SIZE, skb->tail, 
476                                 skb_tailroom(skb), &irlap_param_info);
477         if (ret < 0)
478                 return ret;
479         skb_put(skb, ret);
480
481         /* Insert additional BOFs */
482         ret = irda_param_insert(self, PI_ADD_BOFS, skb->tail, 
483                                 skb_tailroom(skb), &irlap_param_info);
484         if (ret < 0)
485                 return ret;
486         skb_put(skb, ret);
487
488         /* Insert minimum turnaround time */
489         ret = irda_param_insert(self, PI_MIN_TURN_TIME, skb->tail, 
490                                 skb_tailroom(skb), &irlap_param_info);
491         if (ret < 0)
492                 return ret;
493         skb_put(skb, ret);
494
495         /* Insert link disconnect/threshold time */
496         ret = irda_param_insert(self, PI_LINK_DISC, skb->tail, 
497                                 skb_tailroom(skb), &irlap_param_info);
498         if (ret < 0)
499                 return ret;
500         skb_put(skb, ret);
501
502         return 0;
503 }
504
505 /*
506  * Function irlap_param_baud_rate (instance, param, get)
507  *
508  *    Negotiate data-rate
509  *
510  */
511 static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get)
512 {
513         __u16 final;
514
515         struct irlap_cb *self = (struct irlap_cb *) instance;
516
517         ASSERT(self != NULL, return -1;);
518         ASSERT(self->magic == LAP_MAGIC, return -1;);
519
520         if (get) {
521                 param->pv.i = self->qos_rx.baud_rate.bits;
522                 IRDA_DEBUG(2, __FUNCTION__ "(), baud rate = 0x%02x\n", 
523                            param->pv.i);                
524         } else {
525                 /* 
526                  *  Stations must agree on baud rate, so calculate
527                  *  intersection 
528                  */
529                 IRDA_DEBUG(2, "Requested BAUD_RATE: 0x%04x\n", (__u16) param->pv.i);
530                 final = (__u16) param->pv.i & self->qos_rx.baud_rate.bits;
531
532                 IRDA_DEBUG(2, "Final BAUD_RATE: 0x%04x\n", final);
533                 self->qos_tx.baud_rate.bits = final;
534                 self->qos_rx.baud_rate.bits = final;
535         }
536
537         return 0;
538 }
539
540 /*
541  * Function irlap_param_link_disconnect (instance, param, get)
542  *
543  *    Negotiate link disconnect/threshold time. 
544  *
545  */
546 static int irlap_param_link_disconnect(void *instance, irda_param_t *param, 
547                                        int get)
548 {
549         __u16 final;
550         
551         struct irlap_cb *self = (struct irlap_cb *) instance;
552         
553         ASSERT(self != NULL, return -1;);
554         ASSERT(self->magic == LAP_MAGIC, return -1;);
555         
556         if (get)
557                 param->pv.i = self->qos_rx.link_disc_time.bits;
558         else {
559                 /*  
560                  *  Stations must agree on link disconnect/threshold 
561                  *  time.
562                  */
563                 IRDA_DEBUG(2, "LINK_DISC: %02x\n", (__u8) param->pv.i);
564                 final = (__u8) param->pv.i & self->qos_rx.link_disc_time.bits;
565
566                 IRDA_DEBUG(2, "Final LINK_DISC: %02x\n", final);
567                 self->qos_tx.link_disc_time.bits = final;
568                 self->qos_rx.link_disc_time.bits = final;
569         }
570         return 0;
571 }
572
573 /*
574  * Function irlap_param_max_turn_time (instance, param, get)
575  *
576  *    Negotiate the maximum turnaround time. This is a type 1 parameter and
577  *    will be negotiated independently for each station
578  *
579  */
580 static int irlap_param_max_turn_time(void *instance, irda_param_t *param, 
581                                      int get)
582 {
583         struct irlap_cb *self = (struct irlap_cb *) instance;
584         
585         ASSERT(self != NULL, return -1;);
586         ASSERT(self->magic == LAP_MAGIC, return -1;);
587         
588         if (get)
589                 param->pv.i = self->qos_rx.max_turn_time.bits;
590         else
591                 self->qos_tx.max_turn_time.bits = (__u8) param->pv.i;
592
593         return 0;
594 }
595
596 /*
597  * Function irlap_param_data_size (instance, param, get)
598  *
599  *    Negotiate the data size. This is a type 1 parameter and
600  *    will be negotiated independently for each station
601  *
602  */
603 static int irlap_param_data_size(void *instance, irda_param_t *param, int get)
604 {
605         struct irlap_cb *self = (struct irlap_cb *) instance;
606         
607         ASSERT(self != NULL, return -1;);
608         ASSERT(self->magic == LAP_MAGIC, return -1;);
609         
610         if (get)
611                 param->pv.i = self->qos_rx.data_size.bits;
612         else
613                 self->qos_tx.data_size.bits = (__u8) param->pv.i;
614
615         return 0;
616 }
617
618 /*
619  * Function irlap_param_window_size (instance, param, get)
620  *
621  *    Negotiate the window size. This is a type 1 parameter and
622  *    will be negotiated independently for each station
623  *
624  */
625 static int irlap_param_window_size(void *instance, irda_param_t *param, 
626                                    int get)
627 {
628         struct irlap_cb *self = (struct irlap_cb *) instance;
629         
630         ASSERT(self != NULL, return -1;);
631         ASSERT(self->magic == LAP_MAGIC, return -1;);
632         
633         if (get)
634                 param->pv.i = self->qos_rx.window_size.bits;
635         else
636                 self->qos_tx.window_size.bits = (__u8) param->pv.i;
637
638         return 0;
639 }
640
641 /*
642  * Function irlap_param_additional_bofs (instance, param, get)
643  *
644  *    Negotiate additional BOF characters. This is a type 1 parameter and
645  *    will be negotiated independently for each station.
646  */
647 static int irlap_param_additional_bofs(void *instance, irda_param_t *param, int get)
648 {
649         struct irlap_cb *self = (struct irlap_cb *) instance;
650         
651         ASSERT(self != NULL, return -1;);
652         ASSERT(self->magic == LAP_MAGIC, return -1;);
653         
654         if (get)
655                 param->pv.i = self->qos_rx.additional_bofs.bits;
656         else
657                 self->qos_tx.additional_bofs.bits = (__u8) param->pv.i;
658
659         return 0;
660 }
661
662 /*
663  * Function irlap_param_min_turn_time (instance, param, get)
664  *
665  *    Negotiate the minimum turn around time. This is a type 1 parameter and
666  *    will be negotiated independently for each station
667  */
668 static int irlap_param_min_turn_time(void *instance, irda_param_t *param, 
669                                      int get)
670 {
671         struct irlap_cb *self = (struct irlap_cb *) instance;
672         
673         ASSERT(self != NULL, return -1;);
674         ASSERT(self->magic == LAP_MAGIC, return -1;);
675         
676         if (get)
677                 param->pv.i = self->qos_rx.min_turn_time.bits;
678         else
679                 self->qos_tx.min_turn_time.bits = (__u8) param->pv.i;
680
681         return 0;
682 }
683
684 /*
685  * Function irlap_max_line_capacity (speed, max_turn_time, min_turn_time)
686  *
687  *    Calculate the maximum line capacity
688  *
689  */
690 __u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time)
691 {
692         __u32 line_capacity;
693         int i,j;
694
695         IRDA_DEBUG(2, __FUNCTION__ "(), speed=%d, max_turn_time=%d\n",
696                    speed, max_turn_time);
697
698         i = value_index(speed, baud_rates, 10);
699         j = value_index(max_turn_time, max_turn_times, 4);
700
701         ASSERT(((i >=0) && (i <=10)), return 0;);
702         ASSERT(((j >=0) && (j <=4)), return 0;);
703
704         line_capacity = max_line_capacities[i][j];
705
706         IRDA_DEBUG(2, __FUNCTION__ "(), line capacity=%d bytes\n", 
707                    line_capacity);
708         
709         return line_capacity;
710 }
711
712 __u32 irlap_requested_line_capacity(struct qos_info *qos)
713 {       __u32 line_capacity;
714         
715         line_capacity = qos->window_size.value * 
716                 (qos->data_size.value + 6 + qos->additional_bofs.value) +
717                 irlap_min_turn_time_in_bytes(qos->baud_rate.value, 
718                                              qos->min_turn_time.value);
719         
720         IRDA_DEBUG(2, __FUNCTION__ "(), requested line capacity=%d\n",
721                    line_capacity);
722         
723         return line_capacity;                                     
724 }
725
726 void irda_qos_bits_to_value(struct qos_info *qos)
727 {
728         int index;
729
730         ASSERT(qos != NULL, return;);
731         
732         index = msb_index(qos->baud_rate.bits);
733         qos->baud_rate.value = baud_rates[index];
734
735         index = msb_index(qos->data_size.bits);
736         qos->data_size.value = data_sizes[index];
737
738         index = msb_index(qos->window_size.bits);
739         qos->window_size.value = index+1;
740
741         index = msb_index(qos->min_turn_time.bits);
742         qos->min_turn_time.value = min_turn_times[index];
743         
744         index = msb_index(qos->max_turn_time.bits);
745         qos->max_turn_time.value = max_turn_times[index];
746
747         index = msb_index(qos->link_disc_time.bits);
748         qos->link_disc_time.value = link_disc_times[index];
749         
750         index = msb_index(qos->additional_bofs.bits);
751         qos->additional_bofs.value = add_bofs[index];
752 }