Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

qos.c

Go to the documentation of this file.
00001 /*********************************************************************
00002  *                                
00003  * Filename:      qos.c
00004  * Version:       1.0
00005  * Description:   IrLAP QoS parameter negotiation
00006  * Status:        Stable
00007  * Author:        Dag Brattli <dagb@cs.uit.no>
00008  * Created at:    Tue Sep  9 00:00:26 1997
00009  * Modified at:   Fri Apr 14 00:30:04 2000
00010  * Modified by:   Dag Brattli <dagb@cs.uit.no>
00011  * 
00012  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
00013  *     All Rights Reserved.
00014  *     
00015  *     This program is free software; you can redistribute it and/or 
00016  *     modify it under the terms of the GNU General Public License as 
00017  *     published by the Free Software Foundation; either version 2 of 
00018  *     the License, or (at your option) any later version.
00019  * 
00020  *     This program is distributed in the hope that it will be useful,
00021  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00023  *     GNU General Public License for more details.
00024  * 
00025  *     You should have received a copy of the GNU General Public License 
00026  *     along with this program; if not, write to the Free Software 
00027  *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
00028  *     MA 02111-1307 USA
00029  *     
00030  ********************************************************************/
00031 
00032 #include <linux/config.h>
00033 #include <asm/byteorder.h>
00034 
00035 #include <net/irda/irda.h>
00036 #include <net/irda/parameters.h>
00037 #include <net/irda/qos.h>
00038 #include <net/irda/irlap.h>
00039 #ifdef CONFIG_IRDA_COMPRESSION
00040 #include <net/irda/irlap_comp.h>
00041 #include "../../drivers/net/zlib.h"
00042 
00043 #define CI_BZIP2  27 /* Random pick */
00044 #endif
00045 
00046 static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get);
00047 static int irlap_param_link_disconnect(void *instance, irda_param_t *parm, 
00048                                        int get);
00049 static int irlap_param_max_turn_time(void *instance, irda_param_t *param, 
00050                                      int get);
00051 static int irlap_param_data_size(void *instance, irda_param_t *param, int get);
00052 static int irlap_param_window_size(void *instance, irda_param_t *param, 
00053                                    int get);
00054 static int irlap_param_additional_bofs(void *instance, irda_param_t *parm, 
00055                                        int get);
00056 static int irlap_param_min_turn_time(void *instance, irda_param_t *param, 
00057                                      int get);
00058 
00059 __u32 min_turn_times[]  = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
00060 __u32 baud_rates[]      = { 2400, 9600, 19200, 38400, 57600, 115200, 576000, 
00061                             1152000, 4000000, 16000000 };           /* bps */
00062 __u32 data_sizes[]      = { 64, 128, 256, 512, 1024, 2048 };        /* bytes */
00063 __u32 add_bofs[]        = { 48, 24, 12, 5, 3, 2, 1, 0 };            /* bytes */
00064 __u32 max_turn_times[]  = { 500, 250, 100, 50 };                    /* ms */
00065 __u32 link_disc_times[] = { 3, 8, 12, 16, 20, 25, 30, 40 };         /* secs */
00066 
00067 #ifdef CONFIG_IRDA_COMPRESSION
00068 __u32 compressions[] = { CI_BZIP2, CI_DEFLATE, CI_DEFLATE_DRAFT };
00069 #endif
00070 
00071 __u32 max_line_capacities[10][4] = {
00072        /* 500 ms     250 ms  100 ms  50 ms (max turn time) */
00073         {    100,      0,      0,     0 }, /*     2400 bps */
00074         {    400,      0,      0,     0 }, /*     9600 bps */
00075         {    800,      0,      0,     0 }, /*    19200 bps */
00076         {   1600,      0,      0,     0 }, /*    38400 bps */
00077         {   2360,      0,      0,     0 }, /*    57600 bps */
00078         {   4800,   2400,    960,   480 }, /*   115200 bps */
00079         {  28800,  11520,   5760,  2880 }, /*   576000 bps */
00080         {  57600,  28800,  11520,  5760 }, /*  1152000 bps */
00081         { 200000, 100000,  40000, 20000 }, /*  4000000 bps */
00082         { 800000, 400000, 160000, 80000 }, /* 16000000 bps */
00083 };
00084 
00085 static pi_minor_info_t pi_minor_call_table_type_0[] = {
00086         { NULL, 0 },
00087 /* 01 */{ irlap_param_baud_rate,       PV_INTEGER | PV_LITTLE_ENDIAN },
00088         { NULL, 0 },
00089         { NULL, 0 },
00090         { NULL, 0 },
00091         { NULL, 0 },
00092         { NULL, 0 },
00093         { NULL, 0 },
00094 /* 08 */{ irlap_param_link_disconnect, PV_INT_8_BITS }
00095 };
00096 
00097 static pi_minor_info_t pi_minor_call_table_type_1[] = {
00098         { NULL, 0 },
00099         { NULL, 0 },
00100 /* 82 */{ irlap_param_max_turn_time,   PV_INT_8_BITS },
00101 /* 83 */{ irlap_param_data_size,       PV_INT_8_BITS },
00102 /* 84 */{ irlap_param_window_size,     PV_INT_8_BITS },
00103 /* 85 */{ irlap_param_additional_bofs, PV_INT_8_BITS },
00104 /* 86 */{ irlap_param_min_turn_time,   PV_INT_8_BITS },
00105 };
00106 
00107 static pi_major_info_t pi_major_call_table[] = {
00108         { pi_minor_call_table_type_0, 9 },
00109         { pi_minor_call_table_type_1, 7 },
00110 };
00111 
00112 static pi_param_info_t irlap_param_info = { pi_major_call_table, 2, 0x7f, 7 };
00113 
00114 /*
00115  * Function irda_qos_compute_intersection (qos, new)
00116  *
00117  *    Compute the intersection of the old QoS capabilites with new ones
00118  *
00119  */
00120 void irda_qos_compute_intersection(struct qos_info *qos, struct qos_info *new)
00121 {
00122         ASSERT(qos != NULL, return;);
00123         ASSERT(new != NULL, return;);
00124 
00125         /* Apply */
00126         qos->baud_rate.bits       &= new->baud_rate.bits;
00127         qos->window_size.bits     &= new->window_size.bits;
00128         qos->min_turn_time.bits   &= new->min_turn_time.bits;
00129         qos->max_turn_time.bits   &= new->max_turn_time.bits;
00130         qos->data_size.bits       &= new->data_size.bits;
00131         qos->link_disc_time.bits  &= new->link_disc_time.bits;
00132         qos->additional_bofs.bits &= new->additional_bofs.bits;
00133 
00134 #ifdef CONFIG_IRDA_COMPRESSION
00135         qos->compression.bits     &= new->compression.bits;
00136 #endif
00137 
00138         irda_qos_bits_to_value(qos);
00139 }
00140 
00141 /*
00142  * Function irda_init_max_qos_capabilies (qos)
00143  *
00144  *    The purpose of this function is for layers and drivers to be able to
00145  *    set the maximum QoS possible and then "and in" their own limitations
00146  * 
00147  */
00148 void irda_init_max_qos_capabilies(struct qos_info *qos)
00149 {
00150         /* 
00151          *  These are the maximum supported values as specified on pages
00152          *  39-43 in IrLAP
00153          */
00154 
00155         /* LSB is first byte, MSB is second byte */
00156         qos->baud_rate.bits     = 0x01ff; 
00157 
00158         qos->window_size.bits     = 0x7f;
00159         qos->min_turn_time.bits   = 0xff;
00160         qos->max_turn_time.bits   = 0x0f;
00161         qos->data_size.bits       = 0x3f;
00162         qos->link_disc_time.bits  = 0xff;
00163         qos->additional_bofs.bits = 0xff;
00164 
00165 #ifdef CONFIG_IRDA_COMPRESSION  
00166         qos->compression.bits     = 0x03;
00167 #endif
00168 }
00169 
00170 /*
00171  * Function irlap_adjust_qos_settings (qos)
00172  *
00173  *     Adjust QoS settings in case some values are not possible to use because
00174  *     of other settings
00175  */
00176 void irlap_adjust_qos_settings(struct qos_info *qos)
00177 {
00178         __u32 line_capacity;
00179         int index;
00180 
00181         IRDA_DEBUG(2, __FUNCTION__ "()\n");
00182 
00183         /* 
00184          * Not allowed to use a max turn time less than 500 ms if the baudrate
00185          * is less than 115200
00186          */
00187         if ((qos->baud_rate.value < 115200) && 
00188             (qos->max_turn_time.value < 500))
00189         {
00190                 IRDA_DEBUG(0, __FUNCTION__ 
00191                            "(), adjusting max turn time from %d to 500 ms\n",
00192                            qos->max_turn_time.value);
00193                 qos->max_turn_time.value = 500;
00194         }
00195         
00196         /*
00197          * The data size must be adjusted according to the baud rate and max 
00198          * turn time
00199          */
00200         index = value_index(qos->data_size.value, data_sizes);
00201         line_capacity = irlap_max_line_capacity(qos->baud_rate.value, 
00202                                                 qos->max_turn_time.value);
00203 
00204 #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
00205         while ((qos->data_size.value > line_capacity) && (index > 0)) {
00206                 qos->data_size.value = data_sizes[index--];
00207                 IRDA_DEBUG(2, __FUNCTION__ 
00208                            "(), redusing data size to %d\n",
00209                            qos->data_size.value);
00210         }
00211 #else /* Use method descibed in section 6.6.11 of IrLAP */
00212         while (irlap_requested_line_capacity(qos) > line_capacity) {
00213                 ASSERT(index != 0, return;);
00214 
00215                 /* Must be able to send at least one frame */
00216                 if (qos->window_size.value > 1) {
00217                         qos->window_size.value--;
00218                         IRDA_DEBUG(2, __FUNCTION__ 
00219                                    "(), redusing window size to %d\n",
00220                                    qos->window_size.value);
00221                 } else if (index > 1) {
00222                         qos->data_size.value = data_sizes[index--];
00223                         IRDA_DEBUG(2, __FUNCTION__ 
00224                                    "(), redusing data size to %d\n",
00225                                    qos->data_size.value);
00226                 } else {
00227                         WARNING(__FUNCTION__ "(), nothing more we can do!\n");
00228                 }
00229         }
00230 #endif CONFIG_IRDA_DYNAMIC_WINDOW
00231 }
00232 
00233 /*
00234  * Function irlap_negotiate (qos_device, qos_session, skb)
00235  *
00236  *    Negotiate QoS values, not really that much negotiation :-)
00237  *    We just set the QoS capabilities for the peer station
00238  *
00239  */
00240 int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb) 
00241 {
00242         int ret;
00243 #ifdef CONFIG_IRDA_COMPRESSION
00244         int comp_seen = FALSE;
00245 #endif
00246         ret = irda_param_extract_all(self, skb->data, skb->len, 
00247                                      &irlap_param_info);
00248         
00249 #ifdef CONFIG_IRDA_COMPRESSION
00250         if (!comp_seen) {
00251                 IRDA_DEBUG( 4, __FUNCTION__ "(), Compression not seen!\n");
00252                 self->qos_tx.compression.bits = 0x00;
00253                 self->qos_rx.compression.bits = 0x00;
00254         }
00255 #endif
00256 
00257         /* Convert the negotiated bits to values */
00258         irda_qos_bits_to_value(&self->qos_tx);
00259         irda_qos_bits_to_value(&self->qos_rx);
00260 
00261         irlap_adjust_qos_settings(&self->qos_tx);
00262 
00263         IRDA_DEBUG(2, "Setting BAUD_RATE to %d bps.\n", 
00264                    self->qos_tx.baud_rate.value);
00265         IRDA_DEBUG(2, "Setting DATA_SIZE to %d bytes\n",
00266                    self->qos_tx.data_size.value);
00267         IRDA_DEBUG(2, "Setting WINDOW_SIZE to %d\n", 
00268                    self->qos_tx.window_size.value);
00269         IRDA_DEBUG(2, "Setting XBOFS to %d\n", 
00270                    self->qos_tx.additional_bofs.value);
00271         IRDA_DEBUG(2, "Setting MAX_TURN_TIME to %d ms.\n",
00272                    self->qos_tx.max_turn_time.value);
00273         IRDA_DEBUG(2, "Setting MIN_TURN_TIME to %d usecs.\n",
00274                    self->qos_tx.min_turn_time.value);
00275         IRDA_DEBUG(2, "Setting LINK_DISC to %d secs.\n", 
00276                    self->qos_tx.link_disc_time.value);
00277 #ifdef CONFIG_IRDA_COMPRESSION
00278         IRDA_DEBUG(2, "Setting COMPRESSION to %d\n", 
00279                    self->qos_tx.compression.value);
00280 #endif  
00281         return ret;
00282 }
00283 
00284 /*
00285  * Function irlap_insert_negotiation_params (qos, fp)
00286  *
00287  *    Insert QoS negotiaion pararameters into frame
00288  *
00289  */
00290 int irlap_insert_qos_negotiation_params(struct irlap_cb *self, 
00291                                         struct sk_buff *skb)
00292 {
00293         int ret;
00294 
00295         /* Insert data rate */
00296         ret = irda_param_insert(self, PI_BAUD_RATE, skb->tail, 
00297                                 skb_tailroom(skb), &irlap_param_info);
00298         if (ret < 0)
00299                 return ret;
00300         skb_put(skb, ret);
00301 
00302         /* Insert max turnaround time */
00303         ret = irda_param_insert(self, PI_MAX_TURN_TIME, skb->tail, 
00304                                 skb_tailroom(skb), &irlap_param_info);
00305         if (ret < 0)
00306                 return ret;
00307         skb_put(skb, ret);
00308 
00309         /* Insert data size */
00310         ret = irda_param_insert(self, PI_DATA_SIZE, skb->tail, 
00311                                 skb_tailroom(skb), &irlap_param_info);
00312         if (ret < 0)
00313                 return ret;
00314         skb_put(skb, ret);
00315 
00316         /* Insert window size */
00317         ret = irda_param_insert(self, PI_WINDOW_SIZE, skb->tail, 
00318                                 skb_tailroom(skb), &irlap_param_info);
00319         if (ret < 0)
00320                 return ret;
00321         skb_put(skb, ret);
00322 
00323         /* Insert additional BOFs */
00324         ret = irda_param_insert(self, PI_ADD_BOFS, skb->tail, 
00325                                 skb_tailroom(skb), &irlap_param_info);
00326         if (ret < 0)
00327                 return ret;
00328         skb_put(skb, ret);
00329 
00330         /* Insert minimum turnaround time */
00331         ret = irda_param_insert(self, PI_MIN_TURN_TIME, skb->tail, 
00332                                 skb_tailroom(skb), &irlap_param_info);
00333         if (ret < 0)
00334                 return ret;
00335         skb_put(skb, ret);
00336 
00337         /* Insert link disconnect/threshold time */
00338         ret = irda_param_insert(self, PI_LINK_DISC, skb->tail, 
00339                                 skb_tailroom(skb), &irlap_param_info);
00340         if (ret < 0)
00341                 return ret;
00342         skb_put(skb, ret);
00343 
00344         return 0;
00345 }
00346 
00347 /*
00348  * Function irlap_param_baud_rate (instance, param, get)
00349  *
00350  *    Negotiate data-rate
00351  *
00352  */
00353 static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get)
00354 {
00355         __u16 final;
00356 
00357         struct irlap_cb *self = (struct irlap_cb *) instance;
00358 
00359         ASSERT(self != NULL, return -1;);
00360         ASSERT(self->magic == LAP_MAGIC, return -1;);
00361 
00362         if (get) {
00363                 param->pv.i = self->qos_rx.baud_rate.bits;
00364                 IRDA_DEBUG(2, __FUNCTION__ "(), baud rate = 0x%02x\n", 
00365                            param->pv.i);                
00366         } else {
00367                 /* 
00368                  *  Stations must agree on baud rate, so calculate
00369                  *  intersection 
00370                  */
00371                 IRDA_DEBUG(2, "Requested BAUD_RATE: 0x%04x\n", param->pv.s);
00372                 final = param->pv.s & self->qos_rx.baud_rate.bits;
00373 
00374                 IRDA_DEBUG(2, "Final BAUD_RATE: 0x%04x\n", final);
00375                 self->qos_tx.baud_rate.bits = final;
00376                 self->qos_rx.baud_rate.bits = final;
00377         }
00378         return 0;
00379 }
00380 
00381 /*
00382  * Function irlap_param_link_disconnect (instance, param, get)
00383  *
00384  *    Negotiate link disconnect/threshold time. 
00385  *
00386  */
00387 static int irlap_param_link_disconnect(void *instance, irda_param_t *param, 
00388                                        int get)
00389 {
00390         __u16 final;
00391         
00392         struct irlap_cb *self = (struct irlap_cb *) instance;
00393         
00394         ASSERT(self != NULL, return -1;);
00395         ASSERT(self->magic == LAP_MAGIC, return -1;);
00396         
00397         if (get)
00398                 param->pv.b = self->qos_rx.link_disc_time.bits;
00399         else {
00400                 /*  
00401                  *  Stations must agree on link disconnect/threshold 
00402                  *  time.
00403                  */
00404                 IRDA_DEBUG(2, "LINK_DISC: %02x\n", param->pv.b);
00405                 final = param->pv.b & self->qos_rx.link_disc_time.bits;
00406 
00407                 IRDA_DEBUG(2, "Final LINK_DISC: %02x\n", final);
00408                 self->qos_tx.link_disc_time.bits = final;
00409                 self->qos_rx.link_disc_time.bits = final;
00410         }
00411         return 0;
00412 }
00413 
00414 /*
00415  * Function irlap_param_max_turn_time (instance, param, get)
00416  *
00417  *    Negotiate the maximum turnaround time. This is a type 1 parameter and
00418  *    will be negotiated independently for each station
00419  *
00420  */
00421 static int irlap_param_max_turn_time(void *instance, irda_param_t *param, 
00422                                      int get)
00423 {
00424         struct irlap_cb *self = (struct irlap_cb *) instance;
00425         
00426         ASSERT(self != NULL, return -1;);
00427         ASSERT(self->magic == LAP_MAGIC, return -1;);
00428         
00429         if (get)
00430                 param->pv.b = self->qos_rx.max_turn_time.bits;
00431         else
00432                 self->qos_tx.max_turn_time.bits = param->pv.b;
00433 
00434         return 0;
00435 }
00436 
00437 /*
00438  * Function irlap_param_data_size (instance, param, get)
00439  *
00440  *    Negotiate the data size. This is a type 1 parameter and
00441  *    will be negotiated independently for each station
00442  *
00443  */
00444 static int irlap_param_data_size(void *instance, irda_param_t *param, int get)
00445 {
00446         struct irlap_cb *self = (struct irlap_cb *) instance;
00447         
00448         ASSERT(self != NULL, return -1;);
00449         ASSERT(self->magic == LAP_MAGIC, return -1;);
00450         
00451         if (get)
00452                 param->pv.b = self->qos_rx.data_size.bits;
00453         else
00454                 self->qos_tx.data_size.bits = param->pv.b;
00455 
00456         return 0;
00457 }
00458 
00459 /*
00460  * Function irlap_param_window_size (instance, param, get)
00461  *
00462  *    Negotiate the window size. This is a type 1 parameter and
00463  *    will be negotiated independently for each station
00464  *
00465  */
00466 static int irlap_param_window_size(void *instance, irda_param_t *param, 
00467                                    int get)
00468 {
00469         struct irlap_cb *self = (struct irlap_cb *) instance;
00470         
00471         ASSERT(self != NULL, return -1;);
00472         ASSERT(self->magic == LAP_MAGIC, return -1;);
00473         
00474         if (get)
00475                 param->pv.b = self->qos_rx.window_size.bits;
00476         else
00477                 self->qos_tx.window_size.bits = param->pv.b;
00478 
00479         return 0;
00480 }
00481 
00482 /*
00483  * Function irlap_param_additional_bofs (instance, param, get)
00484  *
00485  *    Negotiate additional BOF characters. This is a type 1 parameter and
00486  *    will be negotiated independently for each station.
00487  */
00488 static int irlap_param_additional_bofs(void *instance, irda_param_t *param, int get)
00489 {
00490         struct irlap_cb *self = (struct irlap_cb *) instance;
00491         
00492         ASSERT(self != NULL, return -1;);
00493         ASSERT(self->magic == LAP_MAGIC, return -1;);
00494         
00495         if (get)
00496                 param->pv.b = self->qos_rx.additional_bofs.bits;
00497         else
00498                 self->qos_tx.additional_bofs.bits = param->pv.b;
00499 
00500         return 0;
00501 }
00502 
00503 /*
00504  * Function irlap_param_min_turn_time (instance, param, get)
00505  *
00506  *    Negotiate the minimum turn around time. This is a type 1 parameter and
00507  *    will be negotiated independently for each station
00508  */
00509 static int irlap_param_min_turn_time(void *instance, irda_param_t *param, 
00510                                      int get)
00511 {
00512         struct irlap_cb *self = (struct irlap_cb *) instance;
00513         
00514         ASSERT(self != NULL, return -1;);
00515         ASSERT(self->magic == LAP_MAGIC, return -1;);
00516         
00517         if (get)
00518                 param->pv.b = self->qos_rx.min_turn_time.bits;
00519         else
00520                 self->qos_tx.min_turn_time.bits = param->pv.b;
00521 
00522         return 0;
00523 }
00524 
00525 /*
00526  * Function irlap_max_line_capacity (speed, max_turn_time, min_turn_time)
00527  *
00528  *    Calculate the maximum line capacity
00529  *
00530  */
00531 __u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time)
00532 {
00533         __u32 line_capacity;
00534         int i,j;
00535 
00536         IRDA_DEBUG(2, __FUNCTION__ "(), speed=%d, max_turn_time=%d\n",
00537                    speed, max_turn_time);
00538 
00539         i = value_index(speed, baud_rates);
00540         j = value_index(max_turn_time, max_turn_times);
00541 
00542         ASSERT(((i >=0) && (i <=10)), return 0;);
00543         ASSERT(((j >=0) && (j <=4)), return 0;);
00544 
00545         line_capacity = max_line_capacities[i][j];
00546 
00547         IRDA_DEBUG(2, __FUNCTION__ "(), line capacity=%d bytes\n", 
00548                    line_capacity);
00549         
00550         return line_capacity;
00551 }
00552 
00553 __u32 irlap_requested_line_capacity(struct qos_info *qos)
00554 {       __u32 line_capacity;
00555         
00556         line_capacity = qos->window_size.value * 
00557                 (qos->data_size.value + 6 + qos->additional_bofs.value) +
00558                 irlap_min_turn_time_in_bytes(qos->baud_rate.value, 
00559                                              qos->min_turn_time.value);
00560         
00561         IRDA_DEBUG(2, __FUNCTION__ "(), requested line capacity=%d\n",
00562                    line_capacity);
00563         
00564         return line_capacity;                                     
00565 }
00566 
00567 __u32 irlap_min_turn_time_in_bytes(__u32 speed, __u32 min_turn_time)
00568 {
00569         __u32 bytes;
00570         
00571         bytes = speed * min_turn_time / 10000000;
00572         
00573         return bytes;
00574 }
00575 
00576 __u32 byte_value(__u8 byte, __u32 *array) 
00577 {
00578         int index;
00579 
00580         ASSERT(array != NULL, return -1;);
00581 
00582         index = msb_index(byte);
00583 
00584         return index_value(index, array);
00585 }
00586 
00587 /*
00588  * Function msb_index (word)
00589  *
00590  *    Returns index to most significant bit (MSB) in word
00591  *
00592  */
00593 int msb_index (__u16 word) 
00594 {
00595         __u16 msb = 0x8000;
00596         int index = 15;   /* Current MSB */
00597         
00598         while (msb) {
00599                 if (word & msb)
00600                         break;   /* Found it! */
00601                 msb >>=1;
00602                 index--;
00603         }
00604         
00605         return index;
00606 }
00607 
00608 /*
00609  * Function value_index (value, array)
00610  *
00611  *    Returns the index to the value in the specified array
00612  */
00613 int value_index(__u32 value, __u32 *array) 
00614 {
00615         int i;
00616         
00617         for (i=0;i<8;i++)
00618                 if (array[i] == value)
00619                         break;
00620         return i;
00621 }
00622 
00623 /*
00624  * Function index_value (index, array)
00625  *
00626  *    Returns value to index in array, easy!
00627  *
00628 
00629  */
00630 __u32 index_value(int index, __u32 *array) 
00631 {
00632         return array[index];
00633 }
00634 
00635 void irda_qos_bits_to_value(struct qos_info *qos)
00636 {
00637         int index;
00638 
00639         ASSERT(qos != NULL, return;);
00640         
00641         index = msb_index(qos->baud_rate.bits);
00642         qos->baud_rate.value = baud_rates[index];
00643 
00644         index = msb_index(qos->data_size.bits);
00645         qos->data_size.value = data_sizes[index];
00646 
00647         index = msb_index(qos->window_size.bits);
00648         qos->window_size.value = index+1;
00649 
00650         index = msb_index(qos->min_turn_time.bits);
00651         qos->min_turn_time.value = min_turn_times[index];
00652         
00653         index = msb_index(qos->max_turn_time.bits);
00654         qos->max_turn_time.value = max_turn_times[index];
00655 
00656         index = msb_index(qos->link_disc_time.bits);
00657         qos->link_disc_time.value = link_disc_times[index];
00658         
00659         index = msb_index(qos->additional_bofs.bits);
00660         qos->additional_bofs.value = add_bofs[index];
00661 
00662 #ifdef CONFIG_IRDA_COMPRESSION
00663         index = msb_index(qos->compression.bits);
00664         if (index >= 0)
00665                 qos->compression.value = compressions[index];
00666         else 
00667                 qos->compression.value = 0;
00668 #endif
00669 }
00670 
00671 
00672 
00673 
00674 
00675 
00676