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