qos.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:21k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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