qos.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:20k
源码类别:

嵌入式Linux

开发平台:

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