kernel.org linux-2.6.10
[linux-2.6.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  * My nsc-ircc hardware has troubles receiving 2048 bytes frames at 4 Mb/s,
74  * so adjust to 2042... I don't know if this bug applies only for 2048
75  * bytes frames or all negotiated frame sizes, but you can use the sysctl
76  * to play with this value anyway.
77  * Jean II */
78 unsigned sysctl_max_tx_data_size = 2042;
79 /*
80  * Maximum transmit window, i.e. number of LAP frames between turn-around.
81  * This allow to override what the peer told us. Some peers are buggy and
82  * don't always support what they tell us.
83  * Jean II */
84 unsigned sysctl_max_tx_window = 7;
85
86 static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get);
87 static int irlap_param_link_disconnect(void *instance, irda_param_t *parm, 
88                                        int get);
89 static int irlap_param_max_turn_time(void *instance, irda_param_t *param, 
90                                      int get);
91 static int irlap_param_data_size(void *instance, irda_param_t *param, int get);
92 static int irlap_param_window_size(void *instance, irda_param_t *param, 
93                                    int get);
94 static int irlap_param_additional_bofs(void *instance, irda_param_t *parm, 
95                                        int get);
96 static int irlap_param_min_turn_time(void *instance, irda_param_t *param, 
97                                      int get);
98
99 static __u32 min_turn_times[]  = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
100 static __u32 baud_rates[]      = { 2400, 9600, 19200, 38400, 57600, 115200, 576000, 
101                                    1152000, 4000000, 16000000 };           /* bps */
102 static __u32 data_sizes[]      = { 64, 128, 256, 512, 1024, 2048 };        /* bytes */
103 static __u32 add_bofs[]        = { 48, 24, 12, 5, 3, 2, 1, 0 };            /* bytes */
104 static __u32 max_turn_times[]  = { 500, 250, 100, 50 };                    /* ms */
105 static __u32 link_disc_times[] = { 3, 8, 12, 16, 20, 25, 30, 40 };         /* secs */
106
107 static __u32 max_line_capacities[10][4] = {
108        /* 500 ms     250 ms  100 ms  50 ms (max turn time) */
109         {    100,      0,      0,     0 }, /*     2400 bps */
110         {    400,      0,      0,     0 }, /*     9600 bps */
111         {    800,      0,      0,     0 }, /*    19200 bps */
112         {   1600,      0,      0,     0 }, /*    38400 bps */
113         {   2360,      0,      0,     0 }, /*    57600 bps */
114         {   4800,   2400,    960,   480 }, /*   115200 bps */
115         {  28800,  11520,   5760,  2880 }, /*   576000 bps */
116         {  57600,  28800,  11520,  5760 }, /*  1152000 bps */
117         { 200000, 100000,  40000, 20000 }, /*  4000000 bps */
118         { 800000, 400000, 160000, 80000 }, /* 16000000 bps */
119 };
120
121 static pi_minor_info_t pi_minor_call_table_type_0[] = {
122         { NULL, 0 },
123 /* 01 */{ irlap_param_baud_rate,       PV_INTEGER | PV_LITTLE_ENDIAN },
124         { NULL, 0 },
125         { NULL, 0 },
126         { NULL, 0 },
127         { NULL, 0 },
128         { NULL, 0 },
129         { NULL, 0 },
130 /* 08 */{ irlap_param_link_disconnect, PV_INT_8_BITS }
131 };
132
133 static pi_minor_info_t pi_minor_call_table_type_1[] = {
134         { NULL, 0 },
135         { NULL, 0 },
136 /* 82 */{ irlap_param_max_turn_time,   PV_INT_8_BITS },
137 /* 83 */{ irlap_param_data_size,       PV_INT_8_BITS },
138 /* 84 */{ irlap_param_window_size,     PV_INT_8_BITS },
139 /* 85 */{ irlap_param_additional_bofs, PV_INT_8_BITS },
140 /* 86 */{ irlap_param_min_turn_time,   PV_INT_8_BITS },
141 };
142
143 static pi_major_info_t pi_major_call_table[] = {
144         { pi_minor_call_table_type_0, 9 },
145         { pi_minor_call_table_type_1, 7 },
146 };
147
148 static pi_param_info_t irlap_param_info = { pi_major_call_table, 2, 0x7f, 7 };
149
150 /* ---------------------- LOCAL SUBROUTINES ---------------------- */
151 /* Note : we start with a bunch of local subroutines.
152  * As the compiler is "one pass", this is the only way to get them to
153  * inline properly...
154  * Jean II
155  */
156 /*
157  * Function value_index (value, array, size)
158  *
159  *    Returns the index to the value in the specified array
160  */
161 static inline int value_index(__u32 value, __u32 *array, int size)
162 {
163         int i;
164         
165         for (i=0; i < size; i++)
166                 if (array[i] == value)
167                         break;
168         return i;
169 }
170
171 /*
172  * Function index_value (index, array)
173  *
174  *    Returns value to index in array, easy!
175  *
176  */
177 static inline __u32 index_value(int index, __u32 *array) 
178 {
179         return array[index];
180 }
181
182 /*
183  * Function msb_index (word)
184  *
185  *    Returns index to most significant bit (MSB) in word
186  *
187  */
188 static int msb_index (__u16 word) 
189 {
190         __u16 msb = 0x8000;
191         int index = 15;   /* Current MSB */
192
193         /* Check for buggy peers.
194          * Note : there is a small probability that it could be us, but I
195          * would expect driver authors to catch that pretty early and be
196          * able to check precisely what's going on. If a end user sees this,
197          * it's very likely the peer. - Jean II */
198         if (word == 0) {
199                 WARNING("%s(), Detected buggy peer, adjust null PV to 0x1!\n",
200                          __FUNCTION__);
201                 /* The only safe choice (we don't know the array size) */
202                 word = 0x1;
203         }
204
205         while (msb) {
206                 if (word & msb)
207                         break;   /* Found it! */
208                 msb >>=1;
209                 index--;
210         }
211         return index;
212 }
213
214 /*
215  * Function value_lower_bits (value, array)
216  *
217  *    Returns a bit field marking all possibility lower than value.
218  */
219 static inline int value_lower_bits(__u32 value, __u32 *array, int size, __u16 *field)
220 {
221         int     i;
222         __u16   mask = 0x1;
223         __u16   result = 0x0;
224
225         for (i=0; i < size; i++) {
226                 /* Add the current value to the bit field, shift mask */
227                 result |= mask;
228                 mask <<= 1;
229                 /* Finished ? */
230                 if (array[i] >= value)
231                         break;
232         }
233         /* Send back a valid index */
234         if(i >= size)
235           i = size - 1; /* Last item */
236         *field = result;
237         return i;
238 }
239
240 /*
241  * Function value_highest_bit (value, array)
242  *
243  *    Returns a bit field marking the highest possibility lower than value.
244  */
245 static inline int value_highest_bit(__u32 value, __u32 *array, int size, __u16 *field)
246 {
247         int     i;
248         __u16   mask = 0x1;
249         __u16   result = 0x0;
250
251         for (i=0; i < size; i++) {
252                 /* Finished ? */
253                 if (array[i] <= value)
254                         break;
255                 /* Shift mask */
256                 mask <<= 1;
257         }
258         /* Set the current value to the bit field */
259         result |= mask;
260         /* Send back a valid index */
261         if(i >= size)
262           i = size - 1; /* Last item */
263         *field = result;
264         return i;
265 }
266
267 /* -------------------------- MAIN CALLS -------------------------- */
268
269 /*
270  * Function irda_qos_compute_intersection (qos, new)
271  *
272  *    Compute the intersection of the old QoS capabilities with new ones
273  *
274  */
275 void irda_qos_compute_intersection(struct qos_info *qos, struct qos_info *new)
276 {
277         ASSERT(qos != NULL, return;);
278         ASSERT(new != NULL, return;);
279
280         /* Apply */
281         qos->baud_rate.bits       &= new->baud_rate.bits;
282         qos->window_size.bits     &= new->window_size.bits;
283         qos->min_turn_time.bits   &= new->min_turn_time.bits;
284         qos->max_turn_time.bits   &= new->max_turn_time.bits;
285         qos->data_size.bits       &= new->data_size.bits;
286         qos->link_disc_time.bits  &= new->link_disc_time.bits;
287         qos->additional_bofs.bits &= new->additional_bofs.bits;
288
289         irda_qos_bits_to_value(qos);
290 }
291
292 /*
293  * Function irda_init_max_qos_capabilies (qos)
294  *
295  *    The purpose of this function is for layers and drivers to be able to
296  *    set the maximum QoS possible and then "and in" their own limitations
297  * 
298  */
299 void irda_init_max_qos_capabilies(struct qos_info *qos)
300 {
301         int i;
302         /* 
303          *  These are the maximum supported values as specified on pages
304          *  39-43 in IrLAP
305          */
306
307         /* Use sysctl to set some configurable values... */
308         /* Set configured max speed */
309         i = value_lower_bits(sysctl_max_baud_rate, baud_rates, 10,
310                              &qos->baud_rate.bits);
311         sysctl_max_baud_rate = index_value(i, baud_rates);
312
313         /* Set configured max disc time */
314         i = value_lower_bits(sysctl_max_noreply_time, link_disc_times, 8,
315                              &qos->link_disc_time.bits);
316         sysctl_max_noreply_time = index_value(i, link_disc_times);
317
318         /* LSB is first byte, MSB is second byte */
319         qos->baud_rate.bits    &= 0x03ff;
320
321         qos->window_size.bits     = 0x7f;
322         qos->min_turn_time.bits   = 0xff;
323         qos->max_turn_time.bits   = 0x0f;
324         qos->data_size.bits       = 0x3f;
325         qos->link_disc_time.bits &= 0xff;
326         qos->additional_bofs.bits = 0xff;
327 }
328 EXPORT_SYMBOL(irda_init_max_qos_capabilies);
329
330 /*
331  * Function irlap_adjust_qos_settings (qos)
332  *
333  *     Adjust QoS settings in case some values are not possible to use because
334  *     of other settings
335  */
336 void irlap_adjust_qos_settings(struct qos_info *qos)
337 {
338         __u32 line_capacity;
339         int index;
340
341         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
342
343         /*
344          * Make sure the mintt is sensible.
345          * Main culprit : Ericsson T39. - Jean II
346          */
347         if (sysctl_min_tx_turn_time > qos->min_turn_time.value) {
348                 int i;
349
350                 WARNING("%s(), Detected buggy peer, adjust mtt to %dus!\n",
351                          __FUNCTION__, sysctl_min_tx_turn_time);
352
353                 /* We don't really need bits, but easier this way */
354                 i = value_highest_bit(sysctl_min_tx_turn_time, min_turn_times,
355                                       8, &qos->min_turn_time.bits);
356                 sysctl_min_tx_turn_time = index_value(i, min_turn_times);
357                 qos->min_turn_time.value = sysctl_min_tx_turn_time;
358         }
359
360         /* 
361          * Not allowed to use a max turn time less than 500 ms if the baudrate
362          * is less than 115200
363          */
364         if ((qos->baud_rate.value < 115200) && 
365             (qos->max_turn_time.value < 500))
366         {
367                 IRDA_DEBUG(0, 
368                            "%s(), adjusting max turn time from %d to 500 ms\n",
369                            __FUNCTION__, qos->max_turn_time.value);
370                 qos->max_turn_time.value = 500;
371         }
372         
373         /*
374          * The data size must be adjusted according to the baud rate and max 
375          * turn time
376          */
377         index = value_index(qos->data_size.value, data_sizes, 6);
378         line_capacity = irlap_max_line_capacity(qos->baud_rate.value, 
379                                                 qos->max_turn_time.value);
380
381 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
382         while ((qos->data_size.value > line_capacity) && (index > 0)) {
383                 qos->data_size.value = data_sizes[index--];
384                 IRDA_DEBUG(2, "%s(), reducing data size to %d\n",
385                            __FUNCTION__, qos->data_size.value);
386         }
387 #else /* Use method described in section 6.6.11 of IrLAP */
388         while (irlap_requested_line_capacity(qos) > line_capacity) {
389                 ASSERT(index != 0, return;);
390
391                 /* Must be able to send at least one frame */
392                 if (qos->window_size.value > 1) {
393                         qos->window_size.value--;
394                         IRDA_DEBUG(2, "%s(), reducing window size to %d\n",
395                                    __FUNCTION__, qos->window_size.value);
396                 } else if (index > 1) {
397                         qos->data_size.value = data_sizes[index--];
398                         IRDA_DEBUG(2, "%s(), reducing data size to %d\n",
399                                    __FUNCTION__, qos->data_size.value);
400                 } else {
401                         WARNING("%s(), nothing more we can do!\n",
402                                 __FUNCTION__);
403                 }
404         }
405 #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
406         /*
407          * Fix tx data size according to user limits - Jean II
408          */
409         if (qos->data_size.value > sysctl_max_tx_data_size)
410                 /* Allow non discrete adjustement to avoid loosing capacity */
411                 qos->data_size.value = sysctl_max_tx_data_size;
412         /*
413          * Override Tx window if user request it. - Jean II
414          */
415         if (qos->window_size.value > sysctl_max_tx_window)
416                 qos->window_size.value = sysctl_max_tx_window;
417 }
418
419 /*
420  * Function irlap_negotiate (qos_device, qos_session, skb)
421  *
422  *    Negotiate QoS values, not really that much negotiation :-)
423  *    We just set the QoS capabilities for the peer station
424  *
425  */
426 int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb) 
427 {
428         int ret;
429         
430         ret = irda_param_extract_all(self, skb->data, skb->len, 
431                                      &irlap_param_info);
432         
433         /* Convert the negotiated bits to values */
434         irda_qos_bits_to_value(&self->qos_tx);
435         irda_qos_bits_to_value(&self->qos_rx);
436
437         irlap_adjust_qos_settings(&self->qos_tx);
438
439         IRDA_DEBUG(2, "Setting BAUD_RATE to %d bps.\n", 
440                    self->qos_tx.baud_rate.value);
441         IRDA_DEBUG(2, "Setting DATA_SIZE to %d bytes\n",
442                    self->qos_tx.data_size.value);
443         IRDA_DEBUG(2, "Setting WINDOW_SIZE to %d\n", 
444                    self->qos_tx.window_size.value);
445         IRDA_DEBUG(2, "Setting XBOFS to %d\n", 
446                    self->qos_tx.additional_bofs.value);
447         IRDA_DEBUG(2, "Setting MAX_TURN_TIME to %d ms.\n",
448                    self->qos_tx.max_turn_time.value);
449         IRDA_DEBUG(2, "Setting MIN_TURN_TIME to %d usecs.\n",
450                    self->qos_tx.min_turn_time.value);
451         IRDA_DEBUG(2, "Setting LINK_DISC to %d secs.\n", 
452                    self->qos_tx.link_disc_time.value);
453         return ret;
454 }
455
456 /*
457  * Function irlap_insert_negotiation_params (qos, fp)
458  *
459  *    Insert QoS negotiaion pararameters into frame
460  *
461  */
462 int irlap_insert_qos_negotiation_params(struct irlap_cb *self, 
463                                         struct sk_buff *skb)
464 {
465         int ret;
466
467         /* Insert data rate */
468         ret = irda_param_insert(self, PI_BAUD_RATE, skb->tail, 
469                                 skb_tailroom(skb), &irlap_param_info);
470         if (ret < 0)
471                 return ret;
472         skb_put(skb, ret);
473
474         /* Insert max turnaround time */
475         ret = irda_param_insert(self, PI_MAX_TURN_TIME, skb->tail, 
476                                 skb_tailroom(skb), &irlap_param_info);
477         if (ret < 0)
478                 return ret;
479         skb_put(skb, ret);
480
481         /* Insert data size */
482         ret = irda_param_insert(self, PI_DATA_SIZE, skb->tail, 
483                                 skb_tailroom(skb), &irlap_param_info);
484         if (ret < 0)
485                 return ret;
486         skb_put(skb, ret);
487
488         /* Insert window size */
489         ret = irda_param_insert(self, PI_WINDOW_SIZE, skb->tail, 
490                                 skb_tailroom(skb), &irlap_param_info);
491         if (ret < 0)
492                 return ret;
493         skb_put(skb, ret);
494
495         /* Insert additional BOFs */
496         ret = irda_param_insert(self, PI_ADD_BOFS, skb->tail, 
497                                 skb_tailroom(skb), &irlap_param_info);
498         if (ret < 0)
499                 return ret;
500         skb_put(skb, ret);
501
502         /* Insert minimum turnaround time */
503         ret = irda_param_insert(self, PI_MIN_TURN_TIME, skb->tail, 
504                                 skb_tailroom(skb), &irlap_param_info);
505         if (ret < 0)
506                 return ret;
507         skb_put(skb, ret);
508
509         /* Insert link disconnect/threshold time */
510         ret = irda_param_insert(self, PI_LINK_DISC, skb->tail, 
511                                 skb_tailroom(skb), &irlap_param_info);
512         if (ret < 0)
513                 return ret;
514         skb_put(skb, ret);
515
516         return 0;
517 }
518
519 /*
520  * Function irlap_param_baud_rate (instance, param, get)
521  *
522  *    Negotiate data-rate
523  *
524  */
525 static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get)
526 {
527         __u16 final;
528
529         struct irlap_cb *self = (struct irlap_cb *) instance;
530
531         ASSERT(self != NULL, return -1;);
532         ASSERT(self->magic == LAP_MAGIC, return -1;);
533
534         if (get) {
535                 param->pv.i = self->qos_rx.baud_rate.bits;
536                 IRDA_DEBUG(2, "%s(), baud rate = 0x%02x\n", 
537                            __FUNCTION__, param->pv.i);          
538         } else {
539                 /* 
540                  *  Stations must agree on baud rate, so calculate
541                  *  intersection 
542                  */
543                 IRDA_DEBUG(2, "Requested BAUD_RATE: 0x%04x\n", (__u16) param->pv.i);
544                 final = (__u16) param->pv.i & self->qos_rx.baud_rate.bits;
545
546                 IRDA_DEBUG(2, "Final BAUD_RATE: 0x%04x\n", final);
547                 self->qos_tx.baud_rate.bits = final;
548                 self->qos_rx.baud_rate.bits = final;
549         }
550
551         return 0;
552 }
553
554 /*
555  * Function irlap_param_link_disconnect (instance, param, get)
556  *
557  *    Negotiate link disconnect/threshold time. 
558  *
559  */
560 static int irlap_param_link_disconnect(void *instance, irda_param_t *param, 
561                                        int get)
562 {
563         __u16 final;
564         
565         struct irlap_cb *self = (struct irlap_cb *) instance;
566         
567         ASSERT(self != NULL, return -1;);
568         ASSERT(self->magic == LAP_MAGIC, return -1;);
569         
570         if (get)
571                 param->pv.i = self->qos_rx.link_disc_time.bits;
572         else {
573                 /*  
574                  *  Stations must agree on link disconnect/threshold 
575                  *  time.
576                  */
577                 IRDA_DEBUG(2, "LINK_DISC: %02x\n", (__u8) param->pv.i);
578                 final = (__u8) param->pv.i & self->qos_rx.link_disc_time.bits;
579
580                 IRDA_DEBUG(2, "Final LINK_DISC: %02x\n", final);
581                 self->qos_tx.link_disc_time.bits = final;
582                 self->qos_rx.link_disc_time.bits = final;
583         }
584         return 0;
585 }
586
587 /*
588  * Function irlap_param_max_turn_time (instance, param, get)
589  *
590  *    Negotiate the maximum turnaround time. This is a type 1 parameter and
591  *    will be negotiated independently for each station
592  *
593  */
594 static int irlap_param_max_turn_time(void *instance, irda_param_t *param, 
595                                      int get)
596 {
597         struct irlap_cb *self = (struct irlap_cb *) instance;
598         
599         ASSERT(self != NULL, return -1;);
600         ASSERT(self->magic == LAP_MAGIC, return -1;);
601         
602         if (get)
603                 param->pv.i = self->qos_rx.max_turn_time.bits;
604         else
605                 self->qos_tx.max_turn_time.bits = (__u8) param->pv.i;
606
607         return 0;
608 }
609
610 /*
611  * Function irlap_param_data_size (instance, param, get)
612  *
613  *    Negotiate the data size. This is a type 1 parameter and
614  *    will be negotiated independently for each station
615  *
616  */
617 static int irlap_param_data_size(void *instance, irda_param_t *param, int get)
618 {
619         struct irlap_cb *self = (struct irlap_cb *) instance;
620         
621         ASSERT(self != NULL, return -1;);
622         ASSERT(self->magic == LAP_MAGIC, return -1;);
623         
624         if (get)
625                 param->pv.i = self->qos_rx.data_size.bits;
626         else
627                 self->qos_tx.data_size.bits = (__u8) param->pv.i;
628
629         return 0;
630 }
631
632 /*
633  * Function irlap_param_window_size (instance, param, get)
634  *
635  *    Negotiate the window size. This is a type 1 parameter and
636  *    will be negotiated independently for each station
637  *
638  */
639 static int irlap_param_window_size(void *instance, irda_param_t *param, 
640                                    int get)
641 {
642         struct irlap_cb *self = (struct irlap_cb *) instance;
643         
644         ASSERT(self != NULL, return -1;);
645         ASSERT(self->magic == LAP_MAGIC, return -1;);
646         
647         if (get)
648                 param->pv.i = self->qos_rx.window_size.bits;
649         else
650                 self->qos_tx.window_size.bits = (__u8) param->pv.i;
651
652         return 0;
653 }
654
655 /*
656  * Function irlap_param_additional_bofs (instance, param, get)
657  *
658  *    Negotiate additional BOF characters. This is a type 1 parameter and
659  *    will be negotiated independently for each station.
660  */
661 static int irlap_param_additional_bofs(void *instance, irda_param_t *param, int get)
662 {
663         struct irlap_cb *self = (struct irlap_cb *) instance;
664         
665         ASSERT(self != NULL, return -1;);
666         ASSERT(self->magic == LAP_MAGIC, return -1;);
667         
668         if (get)
669                 param->pv.i = self->qos_rx.additional_bofs.bits;
670         else
671                 self->qos_tx.additional_bofs.bits = (__u8) param->pv.i;
672
673         return 0;
674 }
675
676 /*
677  * Function irlap_param_min_turn_time (instance, param, get)
678  *
679  *    Negotiate the minimum turn around time. This is a type 1 parameter and
680  *    will be negotiated independently for each station
681  */
682 static int irlap_param_min_turn_time(void *instance, irda_param_t *param, 
683                                      int get)
684 {
685         struct irlap_cb *self = (struct irlap_cb *) instance;
686         
687         ASSERT(self != NULL, return -1;);
688         ASSERT(self->magic == LAP_MAGIC, return -1;);
689         
690         if (get)
691                 param->pv.i = self->qos_rx.min_turn_time.bits;
692         else
693                 self->qos_tx.min_turn_time.bits = (__u8) param->pv.i;
694
695         return 0;
696 }
697
698 /*
699  * Function irlap_max_line_capacity (speed, max_turn_time, min_turn_time)
700  *
701  *    Calculate the maximum line capacity
702  *
703  */
704 __u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time)
705 {
706         __u32 line_capacity;
707         int i,j;
708
709         IRDA_DEBUG(2, "%s(), speed=%d, max_turn_time=%d\n",
710                    __FUNCTION__, speed, max_turn_time);
711
712         i = value_index(speed, baud_rates, 10);
713         j = value_index(max_turn_time, max_turn_times, 4);
714
715         ASSERT(((i >=0) && (i <10)), return 0;);
716         ASSERT(((j >=0) && (j <4)), return 0;);
717
718         line_capacity = max_line_capacities[i][j];
719
720         IRDA_DEBUG(2, "%s(), line capacity=%d bytes\n", 
721                    __FUNCTION__, line_capacity);
722         
723         return line_capacity;
724 }
725
726 __u32 irlap_requested_line_capacity(struct qos_info *qos)
727 {       __u32 line_capacity;
728         
729         line_capacity = qos->window_size.value * 
730                 (qos->data_size.value + 6 + qos->additional_bofs.value) +
731                 irlap_min_turn_time_in_bytes(qos->baud_rate.value, 
732                                              qos->min_turn_time.value);
733         
734         IRDA_DEBUG(2, "%s(), requested line capacity=%d\n",
735                    __FUNCTION__, line_capacity);
736         
737         return line_capacity;                                     
738 }
739
740 void irda_qos_bits_to_value(struct qos_info *qos)
741 {
742         int index;
743
744         ASSERT(qos != NULL, return;);
745         
746         index = msb_index(qos->baud_rate.bits);
747         qos->baud_rate.value = baud_rates[index];
748
749         index = msb_index(qos->data_size.bits);
750         qos->data_size.value = data_sizes[index];
751
752         index = msb_index(qos->window_size.bits);
753         qos->window_size.value = index+1;
754
755         index = msb_index(qos->min_turn_time.bits);
756         qos->min_turn_time.value = min_turn_times[index];
757         
758         index = msb_index(qos->max_turn_time.bits);
759         qos->max_turn_time.value = max_turn_times[index];
760
761         index = msb_index(qos->link_disc_time.bits);
762         qos->link_disc_time.value = link_disc_times[index];
763         
764         index = msb_index(qos->additional_bofs.bits);
765         qos->additional_bofs.value = add_bofs[index];
766 }
767 EXPORT_SYMBOL(irda_qos_bits_to_value);