OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [LINUX_2_4_26_OR32/] [linux/] [linux-2.4/] [net/] [irda/] [qos.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*********************************************************************
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 negociated 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
__u32 min_turn_times[]  = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
100
__u32 baud_rates[]      = { 2400, 9600, 19200, 38400, 57600, 115200, 576000,
101
                            1152000, 4000000, 16000000 };           /* bps */
102
__u32 data_sizes[]      = { 64, 128, 256, 512, 1024, 2048 };        /* bytes */
103
__u32 add_bofs[]        = { 48, 24, 12, 5, 3, 2, 1, 0 };            /* bytes */
104
__u32 max_turn_times[]  = { 500, 250, 100, 50 };                    /* ms */
105
__u32 link_disc_times[] = { 3, 8, 12, 16, 20, 25, 30, 40 };         /* secs */
106
 
107
__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
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
static inline __u32 byte_value(__u8 byte, __u32 *array)
215
{
216
        int index;
217
 
218
        ASSERT(array != NULL, return -1;);
219
 
220
        index = msb_index(byte);
221
 
222
        return index_value(index, array);
223
}
224
 
225
/*
226
 * Function value_lower_bits (value, array)
227
 *
228
 *    Returns a bit field marking all possibility lower than value.
229
 */
230
static inline int value_lower_bits(__u32 value, __u32 *array, int size, __u16 *field)
231
{
232
        int     i;
233
        __u16   mask = 0x1;
234
        __u16   result = 0x0;
235
 
236
        for (i=0; i < size; i++) {
237
                /* Add the current value to the bit field, shift mask */
238
                result |= mask;
239
                mask <<= 1;
240
                /* Finished ? */
241
                if (array[i] >= value)
242
                        break;
243
        }
244
        /* Send back a valid index */
245
        if(i >= size)
246
          i = size - 1; /* Last item */
247
        *field = result;
248
        return i;
249
}
250
 
251
/*
252
 * Function value_highest_bit (value, array)
253
 *
254
 *    Returns a bit field marking the highest possibility lower than value.
255
 */
256
static inline int value_highest_bit(__u32 value, __u32 *array, int size, __u16 *field)
257
{
258
        int     i;
259
        __u16   mask = 0x1;
260
        __u16   result = 0x0;
261
 
262
        for (i=0; i < size; i++) {
263
                /* Finished ? */
264
                if (array[i] <= value)
265
                        break;
266
                /* Shift mask */
267
                mask <<= 1;
268
        }
269
        /* Set the current value to the bit field */
270
        result |= mask;
271
        /* Send back a valid index */
272
        if(i >= size)
273
          i = size - 1; /* Last item */
274
        *field = result;
275
        return i;
276
}
277
 
278
/* -------------------------- MAIN CALLS -------------------------- */
279
 
280
/*
281
 * Function irda_qos_compute_intersection (qos, new)
282
 *
283
 *    Compute the intersection of the old QoS capabilites with new ones
284
 *
285
 */
286
void irda_qos_compute_intersection(struct qos_info *qos, struct qos_info *new)
287
{
288
        ASSERT(qos != NULL, return;);
289
        ASSERT(new != NULL, return;);
290
 
291
        /* Apply */
292
        qos->baud_rate.bits       &= new->baud_rate.bits;
293
        qos->window_size.bits     &= new->window_size.bits;
294
        qos->min_turn_time.bits   &= new->min_turn_time.bits;
295
        qos->max_turn_time.bits   &= new->max_turn_time.bits;
296
        qos->data_size.bits       &= new->data_size.bits;
297
        qos->link_disc_time.bits  &= new->link_disc_time.bits;
298
        qos->additional_bofs.bits &= new->additional_bofs.bits;
299
 
300
        irda_qos_bits_to_value(qos);
301
}
302
 
303
/*
304
 * Function irda_init_max_qos_capabilies (qos)
305
 *
306
 *    The purpose of this function is for layers and drivers to be able to
307
 *    set the maximum QoS possible and then "and in" their own limitations
308
 *
309
 */
310
void irda_init_max_qos_capabilies(struct qos_info *qos)
311
{
312
        int i;
313
        /*
314
         *  These are the maximum supported values as specified on pages
315
         *  39-43 in IrLAP
316
         */
317
 
318
        /* Use sysctl to set some configurable values... */
319
        /* Set configured max speed */
320
        i = value_lower_bits(sysctl_max_baud_rate, baud_rates, 10,
321
                             &qos->baud_rate.bits);
322
        sysctl_max_baud_rate = index_value(i, baud_rates);
323
 
324
        /* Set configured max disc time */
325
        i = value_lower_bits(sysctl_max_noreply_time, link_disc_times, 8,
326
                             &qos->link_disc_time.bits);
327
        sysctl_max_noreply_time = index_value(i, link_disc_times);
328
 
329
        /* LSB is first byte, MSB is second byte */
330
        qos->baud_rate.bits    &= 0x03ff;
331
 
332
        qos->window_size.bits     = 0x7f;
333
        qos->min_turn_time.bits   = 0xff;
334
        qos->max_turn_time.bits   = 0x0f;
335
        qos->data_size.bits       = 0x3f;
336
        qos->link_disc_time.bits &= 0xff;
337
        qos->additional_bofs.bits = 0xff;
338
}
339
 
340
/*
341
 * Function irlap_adjust_qos_settings (qos)
342
 *
343
 *     Adjust QoS settings in case some values are not possible to use because
344
 *     of other settings
345
 */
346
void irlap_adjust_qos_settings(struct qos_info *qos)
347
{
348
        __u32 line_capacity;
349
        int index;
350
 
351
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
352
 
353
        /*
354
         * Make sure the mintt is sensible.
355
         * Main culprit : Ericsson T39. - Jean II
356
         */
357
        if (sysctl_min_tx_turn_time > qos->min_turn_time.value) {
358
                int i;
359
 
360
                WARNING("%s(), Detected buggy peer, adjust mtt to %dus!\n",
361
                         __FUNCTION__, sysctl_min_tx_turn_time);
362
 
363
                /* We don't really need bits, but easier this way */
364
                i = value_highest_bit(sysctl_min_tx_turn_time, min_turn_times,
365
                                      8, &qos->min_turn_time.bits);
366
                sysctl_min_tx_turn_time = index_value(i, min_turn_times);
367
                qos->min_turn_time.value = sysctl_min_tx_turn_time;
368
        }
369
 
370
        /*
371
         * Not allowed to use a max turn time less than 500 ms if the baudrate
372
         * is less than 115200
373
         */
374
        if ((qos->baud_rate.value < 115200) &&
375
            (qos->max_turn_time.value < 500))
376
        {
377
                IRDA_DEBUG(0, "%s(), adjusting max turn time from %d to 500 ms\n", __FUNCTION__,
378
                           qos->max_turn_time.value);
379
                qos->max_turn_time.value = 500;
380
        }
381
 
382
        /*
383
         * The data size must be adjusted according to the baud rate and max
384
         * turn time
385
         */
386
        index = value_index(qos->data_size.value, data_sizes, 6);
387
        line_capacity = irlap_max_line_capacity(qos->baud_rate.value,
388
                                                qos->max_turn_time.value);
389
 
390
#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
391
        while ((qos->data_size.value > line_capacity) && (index > 0)) {
392
                qos->data_size.value = data_sizes[index--];
393
                IRDA_DEBUG(2, "%s(), reducing data size to %d\n", __FUNCTION__,
394
                           qos->data_size.value);
395
        }
396
#else /* Use method described in section 6.6.11 of IrLAP */
397
        while (irlap_requested_line_capacity(qos) > line_capacity) {
398
                ASSERT(index != 0, return;);
399
 
400
                /* Must be able to send at least one frame */
401
                if (qos->window_size.value > 1) {
402
                        qos->window_size.value--;
403
                        IRDA_DEBUG(2, "%s(), reducing window size to %d\n", __FUNCTION__,
404
                                   qos->window_size.value);
405
                } else if (index > 1) {
406
                        qos->data_size.value = data_sizes[index--];
407
                        IRDA_DEBUG(2, "%s(), reducing data size to %d\n", __FUNCTION__,
408
                                   qos->data_size.value);
409
                } else {
410
                        WARNING("%s(), nothing more we can do!\n", __FUNCTION__);
411
                }
412
        }
413
#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
414
        /*
415
         * Fix tx data size according to user limits - Jean II
416
         */
417
        if (qos->data_size.value > sysctl_max_tx_data_size)
418
                /* Allow non discrete adjustement to avoid loosing capacity */
419
                qos->data_size.value = sysctl_max_tx_data_size;
420
        /*
421
         * Override Tx window if user request it. - Jean II
422
         */
423
        if (qos->window_size.value > sysctl_max_tx_window)
424
                qos->window_size.value = sysctl_max_tx_window;
425
}
426
 
427
/*
428
 * Function irlap_negotiate (qos_device, qos_session, skb)
429
 *
430
 *    Negotiate QoS values, not really that much negotiation :-)
431
 *    We just set the QoS capabilities for the peer station
432
 *
433
 */
434
int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb)
435
{
436
        int ret;
437
 
438
        ret = irda_param_extract_all(self, skb->data, skb->len,
439
                                     &irlap_param_info);
440
 
441
        /* Convert the negotiated bits to values */
442
        irda_qos_bits_to_value(&self->qos_tx);
443
        irda_qos_bits_to_value(&self->qos_rx);
444
 
445
        irlap_adjust_qos_settings(&self->qos_tx);
446
 
447
        IRDA_DEBUG(2, "Setting BAUD_RATE to %d bps.\n",
448
                   self->qos_tx.baud_rate.value);
449
        IRDA_DEBUG(2, "Setting DATA_SIZE to %d bytes\n",
450
                   self->qos_tx.data_size.value);
451
        IRDA_DEBUG(2, "Setting WINDOW_SIZE to %d\n",
452
                   self->qos_tx.window_size.value);
453
        IRDA_DEBUG(2, "Setting XBOFS to %d\n",
454
                   self->qos_tx.additional_bofs.value);
455
        IRDA_DEBUG(2, "Setting MAX_TURN_TIME to %d ms.\n",
456
                   self->qos_tx.max_turn_time.value);
457
        IRDA_DEBUG(2, "Setting MIN_TURN_TIME to %d usecs.\n",
458
                   self->qos_tx.min_turn_time.value);
459
        IRDA_DEBUG(2, "Setting LINK_DISC to %d secs.\n",
460
                   self->qos_tx.link_disc_time.value);
461
        return ret;
462
}
463
 
464
/*
465
 * Function irlap_insert_negotiation_params (qos, fp)
466
 *
467
 *    Insert QoS negotiaion pararameters into frame
468
 *
469
 */
470
int irlap_insert_qos_negotiation_params(struct irlap_cb *self,
471
                                        struct sk_buff *skb)
472
{
473
        int ret;
474
 
475
        /* Insert data rate */
476
        ret = irda_param_insert(self, PI_BAUD_RATE, skb->tail,
477
                                skb_tailroom(skb), &irlap_param_info);
478
        if (ret < 0)
479
                return ret;
480
        skb_put(skb, ret);
481
 
482
        /* Insert max turnaround time */
483
        ret = irda_param_insert(self, PI_MAX_TURN_TIME, skb->tail,
484
                                skb_tailroom(skb), &irlap_param_info);
485
        if (ret < 0)
486
                return ret;
487
        skb_put(skb, ret);
488
 
489
        /* Insert data size */
490
        ret = irda_param_insert(self, PI_DATA_SIZE, skb->tail,
491
                                skb_tailroom(skb), &irlap_param_info);
492
        if (ret < 0)
493
                return ret;
494
        skb_put(skb, ret);
495
 
496
        /* Insert window size */
497
        ret = irda_param_insert(self, PI_WINDOW_SIZE, skb->tail,
498
                                skb_tailroom(skb), &irlap_param_info);
499
        if (ret < 0)
500
                return ret;
501
        skb_put(skb, ret);
502
 
503
        /* Insert additional BOFs */
504
        ret = irda_param_insert(self, PI_ADD_BOFS, skb->tail,
505
                                skb_tailroom(skb), &irlap_param_info);
506
        if (ret < 0)
507
                return ret;
508
        skb_put(skb, ret);
509
 
510
        /* Insert minimum turnaround time */
511
        ret = irda_param_insert(self, PI_MIN_TURN_TIME, skb->tail,
512
                                skb_tailroom(skb), &irlap_param_info);
513
        if (ret < 0)
514
                return ret;
515
        skb_put(skb, ret);
516
 
517
        /* Insert link disconnect/threshold time */
518
        ret = irda_param_insert(self, PI_LINK_DISC, skb->tail,
519
                                skb_tailroom(skb), &irlap_param_info);
520
        if (ret < 0)
521
                return ret;
522
        skb_put(skb, ret);
523
 
524
        return 0;
525
}
526
 
527
/*
528
 * Function irlap_param_baud_rate (instance, param, get)
529
 *
530
 *    Negotiate data-rate
531
 *
532
 */
533
static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get)
534
{
535
        __u16 final;
536
 
537
        struct irlap_cb *self = (struct irlap_cb *) instance;
538
 
539
        ASSERT(self != NULL, return -1;);
540
        ASSERT(self->magic == LAP_MAGIC, return -1;);
541
 
542
        if (get) {
543
                param->pv.i = self->qos_rx.baud_rate.bits;
544
                IRDA_DEBUG(2, "%s(), baud rate = 0x%02x\n", __FUNCTION__,
545
                           param->pv.i);
546
        } else {
547
                /*
548
                 *  Stations must agree on baud rate, so calculate
549
                 *  intersection
550
                 */
551
                IRDA_DEBUG(2, "Requested BAUD_RATE: 0x%04x\n", (__u16) param->pv.i);
552
                final = (__u16) param->pv.i & self->qos_rx.baud_rate.bits;
553
 
554
                IRDA_DEBUG(2, "Final BAUD_RATE: 0x%04x\n", final);
555
                self->qos_tx.baud_rate.bits = final;
556
                self->qos_rx.baud_rate.bits = final;
557
        }
558
 
559
        return 0;
560
}
561
 
562
/*
563
 * Function irlap_param_link_disconnect (instance, param, get)
564
 *
565
 *    Negotiate link disconnect/threshold time.
566
 *
567
 */
568
static int irlap_param_link_disconnect(void *instance, irda_param_t *param,
569
                                       int get)
570
{
571
        __u16 final;
572
 
573
        struct irlap_cb *self = (struct irlap_cb *) instance;
574
 
575
        ASSERT(self != NULL, return -1;);
576
        ASSERT(self->magic == LAP_MAGIC, return -1;);
577
 
578
        if (get)
579
                param->pv.i = self->qos_rx.link_disc_time.bits;
580
        else {
581
                /*
582
                 *  Stations must agree on link disconnect/threshold
583
                 *  time.
584
                 */
585
                IRDA_DEBUG(2, "LINK_DISC: %02x\n", (__u8) param->pv.i);
586
                final = (__u8) param->pv.i & self->qos_rx.link_disc_time.bits;
587
 
588
                IRDA_DEBUG(2, "Final LINK_DISC: %02x\n", final);
589
                self->qos_tx.link_disc_time.bits = final;
590
                self->qos_rx.link_disc_time.bits = final;
591
        }
592
        return 0;
593
}
594
 
595
/*
596
 * Function irlap_param_max_turn_time (instance, param, get)
597
 *
598
 *    Negotiate the maximum turnaround time. This is a type 1 parameter and
599
 *    will be negotiated independently for each station
600
 *
601
 */
602
static int irlap_param_max_turn_time(void *instance, irda_param_t *param,
603
                                     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.max_turn_time.bits;
612
        else
613
                self->qos_tx.max_turn_time.bits = (__u8) param->pv.i;
614
 
615
        return 0;
616
}
617
 
618
/*
619
 * Function irlap_param_data_size (instance, param, get)
620
 *
621
 *    Negotiate the data size. This is a type 1 parameter and
622
 *    will be negotiated independently for each station
623
 *
624
 */
625
static int irlap_param_data_size(void *instance, irda_param_t *param, int get)
626
{
627
        struct irlap_cb *self = (struct irlap_cb *) instance;
628
 
629
        ASSERT(self != NULL, return -1;);
630
        ASSERT(self->magic == LAP_MAGIC, return -1;);
631
 
632
        if (get)
633
                param->pv.i = self->qos_rx.data_size.bits;
634
        else
635
                self->qos_tx.data_size.bits = (__u8) param->pv.i;
636
 
637
        return 0;
638
}
639
 
640
/*
641
 * Function irlap_param_window_size (instance, param, get)
642
 *
643
 *    Negotiate the window size. This is a type 1 parameter and
644
 *    will be negotiated independently for each station
645
 *
646
 */
647
static int irlap_param_window_size(void *instance, irda_param_t *param,
648
                                   int get)
649
{
650
        struct irlap_cb *self = (struct irlap_cb *) instance;
651
 
652
        ASSERT(self != NULL, return -1;);
653
        ASSERT(self->magic == LAP_MAGIC, return -1;);
654
 
655
        if (get)
656
                param->pv.i = self->qos_rx.window_size.bits;
657
        else
658
                self->qos_tx.window_size.bits = (__u8) param->pv.i;
659
 
660
        return 0;
661
}
662
 
663
/*
664
 * Function irlap_param_additional_bofs (instance, param, get)
665
 *
666
 *    Negotiate additional BOF characters. This is a type 1 parameter and
667
 *    will be negotiated independently for each station.
668
 */
669
static int irlap_param_additional_bofs(void *instance, irda_param_t *param, 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.additional_bofs.bits;
678
        else
679
                self->qos_tx.additional_bofs.bits = (__u8) param->pv.i;
680
 
681
        return 0;
682
}
683
 
684
/*
685
 * Function irlap_param_min_turn_time (instance, param, get)
686
 *
687
 *    Negotiate the minimum turn around time. This is a type 1 parameter and
688
 *    will be negotiated independently for each station
689
 */
690
static int irlap_param_min_turn_time(void *instance, irda_param_t *param,
691
                                     int get)
692
{
693
        struct irlap_cb *self = (struct irlap_cb *) instance;
694
 
695
        ASSERT(self != NULL, return -1;);
696
        ASSERT(self->magic == LAP_MAGIC, return -1;);
697
 
698
        if (get)
699
                param->pv.i = self->qos_rx.min_turn_time.bits;
700
        else
701
                self->qos_tx.min_turn_time.bits = (__u8) param->pv.i;
702
 
703
        return 0;
704
}
705
 
706
/*
707
 * Function irlap_max_line_capacity (speed, max_turn_time, min_turn_time)
708
 *
709
 *    Calculate the maximum line capacity
710
 *
711
 */
712
__u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time)
713
{
714
        __u32 line_capacity;
715
        int i,j;
716
 
717
        IRDA_DEBUG(2, "%s(), speed=%d, max_turn_time=%d\n", __FUNCTION__,
718
                   speed, max_turn_time);
719
 
720
        i = value_index(speed, baud_rates, 10);
721
        j = value_index(max_turn_time, max_turn_times, 4);
722
 
723
        ASSERT(((i >=0) && (i <=10)), return 0;);
724
        ASSERT(((j >=0) && (j <=4)), return 0;);
725
 
726
        line_capacity = max_line_capacities[i][j];
727
 
728
        IRDA_DEBUG(2, "%s(), line capacity=%d bytes\n", __FUNCTION__,
729
                   line_capacity);
730
 
731
        return line_capacity;
732
}
733
 
734
__u32 irlap_requested_line_capacity(struct qos_info *qos)
735
{       __u32 line_capacity;
736
 
737
        line_capacity = qos->window_size.value *
738
                (qos->data_size.value + 6 + qos->additional_bofs.value) +
739
                irlap_min_turn_time_in_bytes(qos->baud_rate.value,
740
                                             qos->min_turn_time.value);
741
 
742
        IRDA_DEBUG(2, "%s(), requested line capacity=%d\n", __FUNCTION__,
743
                   line_capacity);
744
 
745
        return line_capacity;
746
}
747
 
748
void irda_qos_bits_to_value(struct qos_info *qos)
749
{
750
        int index;
751
 
752
        ASSERT(qos != NULL, return;);
753
 
754
        index = msb_index(qos->baud_rate.bits);
755
        qos->baud_rate.value = baud_rates[index];
756
 
757
        index = msb_index(qos->data_size.bits);
758
        qos->data_size.value = data_sizes[index];
759
 
760
        index = msb_index(qos->window_size.bits);
761
        qos->window_size.value = index+1;
762
 
763
        index = msb_index(qos->min_turn_time.bits);
764
        qos->min_turn_time.value = min_turn_times[index];
765
 
766
        index = msb_index(qos->max_turn_time.bits);
767
        qos->max_turn_time.value = max_turn_times[index];
768
 
769
        index = msb_index(qos->link_disc_time.bits);
770
        qos->link_disc_time.value = link_disc_times[index];
771
 
772
        index = msb_index(qos->additional_bofs.bits);
773
        qos->additional_bofs.value = add_bofs[index];
774
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.