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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*********************************************************************
  2.  *                
  3.  * Filename:      irlap.c
  4.  * Version:       1.0
  5.  * Description:   IrLAP implementation for Linux
  6.  * Status:        Stable
  7.  * Author:        Dag Brattli <dagb@cs.uit.no>
  8.  * Created at:    Mon Aug  4 20:40:53 1997
  9.  * Modified at:   Tue Dec 14 09:26:44 1999
  10.  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  11.  * 
  12.  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
  13.  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
  14.  *     
  15.  *     This program is free software; you can redistribute it and/or 
  16.  *     modify it under the terms of the GNU General Public License as 
  17.  *     published by the Free Software Foundation; either version 2 of 
  18.  *     the License, or (at your option) any later version.
  19.  * 
  20.  *     This program is distributed in the hope that it will be useful,
  21.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23.  *     GNU General Public License for more details.
  24.  * 
  25.  *     You should have received a copy of the GNU General Public License 
  26.  *     along with this program; if not, write to the Free Software 
  27.  *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
  28.  *     MA 02111-1307 USA
  29.  *     
  30.  ********************************************************************/
  31. #include <linux/config.h>
  32. #include <linux/slab.h>
  33. #include <linux/string.h>
  34. #include <linux/skbuff.h>
  35. #include <linux/delay.h>
  36. #include <linux/proc_fs.h>
  37. #include <linux/init.h>
  38. #include <linux/random.h>
  39. #include <net/irda/irda.h>
  40. #include <net/irda/irda_device.h>
  41. #include <net/irda/irqueue.h>
  42. #include <net/irda/irlmp.h>
  43. #include <net/irda/irlmp_frame.h>
  44. #include <net/irda/irlap_frame.h>
  45. #include <net/irda/irlap.h>
  46. #include <net/irda/timer.h>
  47. #include <net/irda/qos.h>
  48. hashbin_t *irlap = NULL;
  49. int sysctl_slot_timeout = SLOT_TIMEOUT * 1000 / HZ;
  50. /* This is the delay of missed pf period before generating an event
  51.  * to the application. The spec mandate 3 seconds, but in some cases
  52.  * it's way too long. - Jean II */
  53. int sysctl_warn_noreply_time = 3;
  54. extern void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb);
  55. static void __irlap_close(struct irlap_cb *self);
  56. #ifdef CONFIG_IRDA_DEBUG
  57. static char *lap_reasons[] = {
  58. "ERROR, NOT USED",
  59. "LAP_DISC_INDICATION",
  60. "LAP_NO_RESPONSE",
  61. "LAP_RESET_INDICATION",
  62. "LAP_FOUND_NONE",
  63. "LAP_MEDIA_BUSY",
  64. "LAP_PRIMARY_CONFLICT",
  65. "ERROR, NOT USED",
  66. };
  67. #endif /* CONFIG_IRDA_DEBUG */
  68. #ifdef CONFIG_PROC_FS
  69. int irlap_proc_read(char *, char **, off_t, int);
  70. #endif /* CONFIG_PROC_FS */
  71. int __init irlap_init(void)
  72. {
  73. /* Allocate master array */
  74. irlap = hashbin_new(HB_LOCAL);
  75. if (irlap == NULL) {
  76.         ERROR("%s(), can't allocate irlap hashbin!n", __FUNCTION__);
  77. return -ENOMEM;
  78. }
  79. return 0;
  80. }
  81. void irlap_cleanup(void)
  82. {
  83. ASSERT(irlap != NULL, return;);
  84. hashbin_delete(irlap, (FREE_FUNC) __irlap_close);
  85. }
  86. /*
  87.  * Function irlap_open (driver)
  88.  *
  89.  *    Initialize IrLAP layer
  90.  *
  91.  */
  92. struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos,
  93.     char * hw_name)
  94. {
  95. struct irlap_cb *self;
  96. IRDA_DEBUG(4, "%s()n", __FUNCTION__);
  97. /* Initialize the irlap structure. */
  98. self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL);
  99. if (self == NULL)
  100. return NULL;
  101. memset(self, 0, sizeof(struct irlap_cb));
  102. self->magic = LAP_MAGIC;
  103. /* Make a binding between the layers */
  104. self->netdev = dev;
  105. self->qos_dev = qos;
  106. /* Copy hardware name */
  107. if(hw_name != NULL) {
  108. strncpy(self->hw_name, hw_name, 2*IFNAMSIZ);
  109. self->hw_name[2*IFNAMSIZ] = '';
  110. } else {
  111. self->hw_name[0] = '';
  112. }
  113. /* FIXME: should we get our own field? */
  114. dev->atalk_ptr = self;
  115. self->state = LAP_OFFLINE;
  116. /* Initialize transmit queue */
  117. skb_queue_head_init(&self->txq);
  118. skb_queue_head_init(&self->txq_ultra);
  119. skb_queue_head_init(&self->wx_list);
  120. /* My unique IrLAP device address! */
  121. get_random_bytes(&self->saddr, sizeof(self->saddr));
  122. memcpy(dev->dev_addr, &self->saddr, 4);
  123. init_timer(&self->slot_timer);
  124. init_timer(&self->query_timer);
  125. init_timer(&self->discovery_timer);
  126. init_timer(&self->final_timer);
  127. init_timer(&self->poll_timer);
  128. init_timer(&self->wd_timer);
  129. init_timer(&self->backoff_timer);
  130. init_timer(&self->media_busy_timer);
  131. irlap_apply_default_connection_parameters(self);
  132. self->N3 = 3; /* # connections attemts to try before giving up */
  133. self->state = LAP_NDM;
  134. hashbin_insert(irlap, (irda_queue_t *) self, self->saddr, NULL);
  135. irlmp_register_link(self, self->saddr, &self->notify);
  136. return self;
  137. }
  138. /*
  139.  * Function __irlap_close (self)
  140.  *
  141.  *    Remove IrLAP and all allocated memory. Stop any pending timers.
  142.  *
  143.  */
  144. static void __irlap_close(struct irlap_cb *self)
  145. {
  146. ASSERT(self != NULL, return;);
  147. ASSERT(self->magic == LAP_MAGIC, return;);
  148. /* Stop timers */
  149. del_timer(&self->slot_timer);
  150. del_timer(&self->query_timer);
  151. del_timer(&self->discovery_timer);
  152. del_timer(&self->final_timer);
  153. del_timer(&self->poll_timer);
  154. del_timer(&self->wd_timer);
  155. del_timer(&self->backoff_timer);
  156. del_timer(&self->media_busy_timer);
  157. irlap_flush_all_queues(self);
  158.        
  159. self->magic = 0;
  160. kfree(self);
  161. }
  162. /*
  163.  * Function irlap_close (self)
  164.  *
  165.  *    Remove IrLAP instance
  166.  *
  167.  */
  168. void irlap_close(struct irlap_cb *self) 
  169. {
  170. struct irlap_cb *lap;
  171. IRDA_DEBUG(4, "%s()n", __FUNCTION__);
  172. ASSERT(self != NULL, return;);
  173. ASSERT(self->magic == LAP_MAGIC, return;);
  174. irlap_disconnect_indication(self, LAP_DISC_INDICATION);
  175. irlmp_unregister_link(self->saddr);
  176. self->notify.instance = NULL;
  177. /* Be sure that we manage to remove ourself from the hash */
  178. lap = hashbin_remove(irlap, self->saddr, NULL);
  179. if (!lap) {
  180. IRDA_DEBUG(1, "%s(), Didn't find myself!n", __FUNCTION__);
  181. return;
  182. }
  183. __irlap_close(lap);
  184. }
  185. /*
  186.  * Function irlap_connect_indication (self, skb)
  187.  *
  188.  *    Another device is attempting to make a connection
  189.  *
  190.  */
  191. void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb) 
  192. {
  193. IRDA_DEBUG(4, "%s()n", __FUNCTION__);
  194. ASSERT(self != NULL, return;);
  195. ASSERT(self->magic == LAP_MAGIC, return;);
  196. irlap_init_qos_capabilities(self, NULL); /* No user QoS! */
  197. skb_get(skb); /*LEVEL4*/
  198. irlmp_link_connect_indication(self->notify.instance, self->saddr, 
  199.       self->daddr, &self->qos_tx, skb);
  200. }
  201. /*
  202.  * Function irlap_connect_response (self, skb)
  203.  *
  204.  *    Service user has accepted incoming connection
  205.  *
  206.  */
  207. void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb) 
  208. {
  209. IRDA_DEBUG(4, "%s()n", __FUNCTION__);
  210. irlap_do_event(self, CONNECT_RESPONSE, skb, NULL);
  211. kfree_skb(skb);
  212. }
  213. /*
  214.  * Function irlap_connect_request (self, daddr, qos_user, sniff)
  215.  *
  216.  *    Request connection with another device, sniffing is not implemented 
  217.  *    yet.
  218.  *
  219.  */
  220. void irlap_connect_request(struct irlap_cb *self, __u32 daddr, 
  221.    struct qos_info *qos_user, int sniff) 
  222. {
  223. IRDA_DEBUG(3, "%s(), daddr=0x%08xn", __FUNCTION__, daddr);
  224. ASSERT(self != NULL, return;);
  225. ASSERT(self->magic == LAP_MAGIC, return;);
  226.   self->daddr = daddr;
  227. /*
  228.  *  If the service user specifies QoS values for this connection, 
  229.  *  then use them
  230.  */
  231. irlap_init_qos_capabilities(self, qos_user);
  232. if ((self->state == LAP_NDM) && !self->media_busy)
  233. irlap_do_event(self, CONNECT_REQUEST, NULL, NULL);
  234. else
  235. self->connect_pending = TRUE;
  236. }
  237. /*
  238.  * Function irlap_connect_confirm (self, skb)
  239.  *
  240.  *    Connection request has been accepted
  241.  *
  242.  */
  243. void irlap_connect_confirm(struct irlap_cb *self, struct sk_buff *skb)
  244. {
  245. IRDA_DEBUG(4, "%s()n", __FUNCTION__);
  246. ASSERT(self != NULL, return;);
  247. ASSERT(self->magic == LAP_MAGIC, return;);
  248. skb_get(skb); /*LEVEL4*/
  249. irlmp_link_connect_confirm(self->notify.instance, &self->qos_tx, skb);
  250. }
  251. /*
  252.  * Function irlap_data_indication (self, skb)
  253.  *
  254.  *    Received data frames from IR-port, so we just pass them up to 
  255.  *    IrLMP for further processing
  256.  *
  257.  */
  258. void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb,
  259.    int unreliable) 
  260. {
  261. /* Hide LAP header from IrLMP layer */
  262. skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
  263. skb_get(skb); /*LEVEL4*/
  264. irlmp_link_data_indication(self->notify.instance, skb, unreliable);
  265. }
  266. /*
  267.  * Function irlap_data_request (self, skb)
  268.  *
  269.  *    Queue data for transmission, must wait until XMIT state
  270.  *
  271.  */
  272. void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb, 
  273. int unreliable)
  274. {
  275. ASSERT(self != NULL, return;);
  276. ASSERT(self->magic == LAP_MAGIC, return;);
  277. IRDA_DEBUG(3, "%s()n", __FUNCTION__);
  278. ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER), 
  279.        return;);
  280. skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
  281. /*  
  282.  *  Must set frame format now so that the rest of the code knows 
  283.  *  if its dealing with an I or an UI frame
  284.  */
  285. if (unreliable)
  286. skb->data[1] = UI_FRAME;
  287. else
  288. skb->data[1] = I_FRAME;
  289. /* Add at the end of the queue (keep ordering) - Jean II */
  290. skb_queue_tail(&self->txq, skb);
  291. /* 
  292.  *  Send event if this frame only if we are in the right state 
  293.  *  FIXME: udata should be sent first! (skb_queue_head?)
  294.  */
  295.    if ((self->state == LAP_XMIT_P) || (self->state == LAP_XMIT_S)) {
  296. /* If we are not already processing the Tx queue, trigger
  297.  * transmission immediately - Jean II */
  298. if((skb_queue_len(&self->txq) <= 1) && (!self->local_busy))
  299. irlap_do_event(self, DATA_REQUEST, skb, NULL);
  300. /* Otherwise, the packets will be sent normally at the
  301.  * next pf-poll - Jean II */
  302. }
  303. }
  304. /*
  305.  * Function irlap_unitdata_request (self, skb)
  306.  *
  307.  *    Send Ultra data. This is data that must be sent outside any connection
  308.  *
  309.  */
  310. #ifdef CONFIG_IRDA_ULTRA
  311. void irlap_unitdata_request(struct irlap_cb *self, struct sk_buff *skb)
  312. {
  313. ASSERT(self != NULL, return;);
  314. ASSERT(self->magic == LAP_MAGIC, return;);
  315. IRDA_DEBUG(3, "%s()n", __FUNCTION__);
  316. ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER), 
  317.        return;);
  318. skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
  319. skb->data[0] = CBROADCAST;
  320. skb->data[1] = UI_FRAME;
  321. skb_queue_tail(&self->txq_ultra, skb);
  322. irlap_do_event(self, SEND_UI_FRAME, NULL, NULL);
  323. }
  324. #endif /*CONFIG_IRDA_ULTRA */
  325. /*
  326.  * Function irlap_udata_indication (self, skb)
  327.  *
  328.  *    Receive Ultra data. This is data that is received outside any connection
  329.  *
  330.  */
  331. #ifdef CONFIG_IRDA_ULTRA
  332. void irlap_unitdata_indication(struct irlap_cb *self, struct sk_buff *skb)
  333. {
  334. IRDA_DEBUG(1, "%s()n", __FUNCTION__); 
  335. ASSERT(self != NULL, return;);
  336. ASSERT(self->magic == LAP_MAGIC, return;);
  337. ASSERT(skb != NULL, return;);
  338. /* Hide LAP header from IrLMP layer */
  339. skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
  340. skb_get(skb); /*LEVEL4*/
  341. irlmp_link_unitdata_indication(self->notify.instance, skb);
  342. }
  343. #endif /* CONFIG_IRDA_ULTRA */
  344. /*
  345.  * Function irlap_disconnect_request (void)
  346.  *
  347.  *    Request to disconnect connection by service user
  348.  */
  349. void irlap_disconnect_request(struct irlap_cb *self) 
  350. {
  351. IRDA_DEBUG(3, "%s()n", __FUNCTION__);
  352. ASSERT(self != NULL, return;);
  353. ASSERT(self->magic == LAP_MAGIC, return;);
  354. /* Don't disconnect until all data frames are successfully sent */
  355. if (skb_queue_len(&self->txq) > 0) {
  356. self->disconnect_pending = TRUE;
  357. return;
  358. }
  359. /* Check if we are in the right state for disconnecting */
  360. switch (self->state) {
  361. case LAP_XMIT_P:        /* FALLTROUGH */
  362. case LAP_XMIT_S:        /* FALLTROUGH */
  363.   case LAP_CONN:          /* FALLTROUGH */
  364.   case LAP_RESET_WAIT:    /* FALLTROUGH */
  365.   case LAP_RESET_CHECK:   
  366. irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);
  367. break;
  368. default:
  369. IRDA_DEBUG(2, "%s(), disconnect pending!n", __FUNCTION__);
  370. self->disconnect_pending = TRUE;
  371. break;
  372. }
  373. }
  374. /*
  375.  * Function irlap_disconnect_indication (void)
  376.  *
  377.  *    Disconnect request from other device
  378.  *
  379.  */
  380. void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason) 
  381. {
  382. IRDA_DEBUG(1, "%s(), reason=%sn", __FUNCTION__, lap_reasons[reason]); 
  383. ASSERT(self != NULL, return;);
  384. ASSERT(self->magic == LAP_MAGIC, return;);
  385. /* Flush queues */
  386. irlap_flush_all_queues(self);
  387. switch (reason) {
  388. case LAP_RESET_INDICATION:
  389. IRDA_DEBUG(1, "%s(), Sending reset request!n", __FUNCTION__);
  390. irlap_do_event(self, RESET_REQUEST, NULL, NULL);
  391. break;
  392. case LAP_NO_RESPONSE:    /* FALLTROUGH */
  393. case LAP_DISC_INDICATION:  /* FALLTROUGH */
  394. case LAP_FOUND_NONE:       /* FALLTROUGH */
  395. case LAP_MEDIA_BUSY:
  396. irlmp_link_disconnect_indication(self->notify.instance, self, 
  397.  reason, NULL);
  398. break;
  399. default:
  400. ERROR("%s(), Unknown reason %dn", __FUNCTION__, reason);
  401. }
  402. }
  403. /*
  404.  * Function irlap_discovery_request (gen_addr_bit)
  405.  *
  406.  *    Start one single discovery operation.
  407.  *
  408.  */
  409. void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery) 
  410. {
  411. struct irlap_info info;
  412. ASSERT(self != NULL, return;);
  413. ASSERT(self->magic == LAP_MAGIC, return;);
  414. ASSERT(discovery != NULL, return;);
  415. IRDA_DEBUG(4, "%s(), nslots = %dn", __FUNCTION__, discovery->nslots);
  416. ASSERT((discovery->nslots == 1) || (discovery->nslots == 6) ||
  417.        (discovery->nslots == 8) || (discovery->nslots == 16), 
  418.        return;);
  419.    /* Discovery is only possible in NDM mode */
  420. if (self->state != LAP_NDM) {
  421. IRDA_DEBUG(4, "%s(), discovery only possible in NDM moden",
  422. __FUNCTION__);
  423. irlap_discovery_confirm(self, NULL);
  424. /* Note : in theory, if we are not in NDM, we could postpone
  425.  * the discovery like we do for connection request.
  426.  * In practice, it's not worth it. If the media was busy,
  427.  * it's likely next time around it won't be busy. If we are
  428.  * in REPLY state, we will get passive discovery info & event.
  429.  * Jean II */
  430. return;
  431. }
  432. /* Check if last discovery request finished in time, or if
  433.  * it was aborted due to the media busy flag. */
  434. if (self->discovery_log != NULL) {
  435. hashbin_delete(self->discovery_log, (FREE_FUNC) kfree);
  436. self->discovery_log = NULL;
  437. }
  438. self->discovery_log= hashbin_new(HB_LOCAL);
  439. info.S = discovery->nslots; /* Number of slots */
  440. info.s = 0; /* Current slot */
  441. self->discovery_cmd = discovery;
  442. info.discovery = discovery;
  443. /* sysctl_slot_timeout bounds are checked in irsysctl.c - Jean II */
  444. self->slot_timeout = sysctl_slot_timeout * HZ / 1000;
  445. irlap_do_event(self, DISCOVERY_REQUEST, NULL, &info);
  446. }
  447. /*
  448.  * Function irlap_discovery_confirm (log)
  449.  *
  450.  *    A device has been discovered in front of this station, we
  451.  *    report directly to LMP.
  452.  */
  453. void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log) 
  454. {
  455. ASSERT(self != NULL, return;);
  456. ASSERT(self->magic == LAP_MAGIC, return;);
  457. ASSERT(self->notify.instance != NULL, return;);
  458. /* 
  459.  * Check for successful discovery, since we are then allowed to clear 
  460.  * the media busy condition (IrLAP 6.13.4 - p.94). This should allow
  461.  * us to make connection attempts much faster and easier (i.e. no
  462.  * collisions).
  463.  * Setting media busy to false will also generate an event allowing
  464.  * to process pending events in NDM state machine.
  465.  * Note : the spec doesn't define what's a successful discovery is.
  466.  * If we want Ultra to work, it's successful even if there is
  467.  * nobody discovered - Jean II
  468.  */
  469. if (discovery_log)
  470. irda_device_set_media_busy(self->netdev, FALSE);
  471. /* Inform IrLMP */
  472. irlmp_link_discovery_confirm(self->notify.instance, discovery_log);
  473. }
  474. /*
  475.  * Function irlap_discovery_indication (log)
  476.  *
  477.  *    Somebody is trying to discover us!
  478.  *
  479.  */
  480. void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery) 
  481. {
  482. IRDA_DEBUG(4, "%s()n", __FUNCTION__);
  483. ASSERT(self != NULL, return;);
  484. ASSERT(self->magic == LAP_MAGIC, return;);
  485. ASSERT(discovery != NULL, return;);
  486. ASSERT(self->notify.instance != NULL, return;);
  487. /* A device is very likely to connect immediately after it performs
  488.  * a successful discovery. This means that in our case, we are much
  489.  * more likely to receive a connection request over the medium.
  490.  * So, we backoff to avoid collisions.
  491.  * IrLAP spec 6.13.4 suggest 100ms...
  492.  * Note : this little trick actually make a *BIG* difference. If I set
  493.  * my Linux box with discovery enabled and one Ultra frame sent every
  494.  * second, my Palm has no trouble connecting to it every time !
  495.  * Jean II */
  496. irda_device_set_media_busy(self->netdev, SMALL);
  497. irlmp_link_discovery_indication(self->notify.instance, discovery);
  498. }
  499. /*
  500.  * Function irlap_status_indication (quality_of_link)
  501.  *
  502.  *    
  503.  *
  504.  */
  505. void irlap_status_indication(struct irlap_cb *self, int quality_of_link) 
  506. {
  507. switch (quality_of_link) {
  508. case STATUS_NO_ACTIVITY:
  509. MESSAGE("IrLAP, no activity on link!n");
  510. break;
  511. case STATUS_NOISY:
  512. MESSAGE("IrLAP, noisy link!n");
  513. break;
  514. default:
  515. break;
  516. }
  517. irlmp_status_indication(self->notify.instance,
  518. quality_of_link, LOCK_NO_CHANGE);
  519. }
  520. /*
  521.  * Function irlap_reset_indication (void)
  522.  *
  523.  *    
  524.  *
  525.  */
  526. void irlap_reset_indication(struct irlap_cb *self)
  527. {
  528. IRDA_DEBUG(1, "%s()n", __FUNCTION__);
  529. ASSERT(self != NULL, return;);
  530. ASSERT(self->magic == LAP_MAGIC, return;);
  531. if (self->state == LAP_RESET_WAIT)
  532. irlap_do_event(self, RESET_REQUEST, NULL, NULL);
  533. else
  534. irlap_do_event(self, RESET_RESPONSE, NULL, NULL);
  535. }
  536. /*
  537.  * Function irlap_reset_confirm (void)
  538.  *
  539.  *    
  540.  *
  541.  */
  542. void irlap_reset_confirm(void)
  543. {
  544.   IRDA_DEBUG(1, "%s()n", __FUNCTION__);
  545. }
  546. /*
  547.  * Function irlap_generate_rand_time_slot (S, s)
  548.  *
  549.  *    Generate a random time slot between s and S-1 where
  550.  *    S = Number of slots (0 -> S-1)
  551.  *    s = Current slot
  552.  */
  553. int irlap_generate_rand_time_slot(int S, int s) 
  554. {
  555. static int rand;
  556. int slot;
  557. ASSERT((S - s) > 0, return 0;);
  558. rand += jiffies;
  559. rand ^= (rand << 12);
  560. rand ^= (rand >> 20);
  561. slot = s + rand % (S-s);
  562. ASSERT((slot >= s) || (slot < S), return 0;);
  563. return slot;
  564. }
  565. /*
  566.  * Function irlap_update_nr_received (nr)
  567.  *
  568.  *    Remove all acknowledged frames in current window queue. This code is 
  569.  *    not intuitive and you should not try to change it. If you think it
  570.  *    contains bugs, please mail a patch to the author instead.
  571.  */
  572. void irlap_update_nr_received(struct irlap_cb *self, int nr) 
  573. {
  574. struct sk_buff *skb = NULL;
  575. int count = 0;
  576. /*
  577.          * Remove all the ack-ed frames from the window queue.
  578.          */
  579. /* 
  580.  *  Optimize for the common case. It is most likely that the receiver
  581.  *  will acknowledge all the frames we have sent! So in that case we
  582.  *  delete all frames stored in window.
  583.  */
  584. if (nr == self->vs) {
  585. while ((skb = skb_dequeue(&self->wx_list)) != NULL) {
  586. dev_kfree_skb(skb);
  587. }
  588. /* The last acked frame is the next to send minus one */
  589. self->va = nr - 1;
  590. } else {
  591. /* Remove all acknowledged frames in current window */
  592. while ((skb_peek(&self->wx_list) != NULL) && 
  593.        (((self->va+1) % 8) != nr)) 
  594. {
  595. skb = skb_dequeue(&self->wx_list);
  596. dev_kfree_skb(skb);
  597. self->va = (self->va + 1) % 8;
  598. count++;
  599. }
  600. }
  601. /* Advance window */
  602. self->window = self->window_size - skb_queue_len(&self->wx_list);
  603. }
  604. /*
  605.  * Function irlap_validate_ns_received (ns)
  606.  *
  607.  *    Validate the next to send (ns) field from received frame.
  608.  */
  609. int irlap_validate_ns_received(struct irlap_cb *self, int ns) 
  610. {
  611. /*  ns as expected?  */
  612. if (ns == self->vr)
  613. return NS_EXPECTED;
  614. /*
  615.  *  Stations are allowed to treat invalid NS as unexpected NS
  616.  *  IrLAP, Recv ... with-invalid-Ns. p. 84
  617.  */
  618. return NS_UNEXPECTED;
  619. /* return NR_INVALID; */
  620. }
  621. /*
  622.  * Function irlap_validate_nr_received (nr)
  623.  *
  624.  *    Validate the next to receive (nr) field from received frame.
  625.  *
  626.  */
  627. int irlap_validate_nr_received(struct irlap_cb *self, int nr) 
  628. {
  629. /*  nr as expected?  */
  630. if (nr == self->vs) {
  631. IRDA_DEBUG(4, "%s(), expected!n", __FUNCTION__);
  632. return NR_EXPECTED;
  633. }
  634. /*
  635.  *  unexpected nr? (but within current window), first we check if the 
  636.  *  ns numbers of the frames in the current window wrap.
  637.  */
  638. if (self->va < self->vs) {
  639. if ((nr >= self->va) && (nr <= self->vs))
  640. return NR_UNEXPECTED;
  641. } else {
  642. if ((nr >= self->va) || (nr <= self->vs)) 
  643. return NR_UNEXPECTED;
  644. }
  645. /* Invalid nr!  */
  646. return NR_INVALID;
  647. }
  648. /*
  649.  * Function irlap_initiate_connection_state ()
  650.  *
  651.  *    Initialize the connection state parameters
  652.  *
  653.  */
  654. void irlap_initiate_connection_state(struct irlap_cb *self) 
  655. {
  656. IRDA_DEBUG(4, "%s()n", __FUNCTION__);
  657. ASSERT(self != NULL, return;);
  658. ASSERT(self->magic == LAP_MAGIC, return;);
  659. /* Next to send and next to receive */
  660. self->vs = self->vr = 0;
  661. /* Last frame which got acked (0 - 1) % 8 */
  662. self->va = 7;
  663. self->window = 1;
  664. self->remote_busy = FALSE;
  665. self->retry_count = 0;
  666. }
  667. /*
  668.  * Function irlap_wait_min_turn_around (self, qos)
  669.  *
  670.  *    Wait negotiated minimum turn around time, this function actually sets
  671.  *    the number of BOS's that must be sent before the next transmitted
  672.  *    frame in order to delay for the specified amount of time. This is
  673.  *    done to avoid using timers, and the forbidden udelay!
  674.  */
  675. void irlap_wait_min_turn_around(struct irlap_cb *self, struct qos_info *qos) 
  676. {
  677. __u32 min_turn_time;
  678. __u32 speed;
  679. /* Get QoS values.  */
  680. speed = qos->baud_rate.value;
  681. min_turn_time = qos->min_turn_time.value;
  682. /* No need to calculate XBOFs for speeds over 115200 bps */
  683. if (speed > 115200) {
  684. self->mtt_required = min_turn_time;
  685. return;
  686. }
  687. /*  
  688.  *  Send additional BOF's for the next frame for the requested
  689.  *  min turn time, so now we must calculate how many chars (XBOF's) we 
  690.  *  must send for the requested time period (min turn time)
  691.  */
  692. self->xbofs_delay = irlap_min_turn_time_in_bytes(speed, min_turn_time);
  693. }
  694. /*
  695.  * Function irlap_flush_all_queues (void)
  696.  *
  697.  *    Flush all queues
  698.  *
  699.  */
  700. void irlap_flush_all_queues(struct irlap_cb *self) 
  701. {
  702. struct sk_buff* skb;
  703. ASSERT(self != NULL, return;);
  704. ASSERT(self->magic == LAP_MAGIC, return;);
  705. /* Free transmission queue */
  706. while ((skb = skb_dequeue(&self->txq)) != NULL)
  707. dev_kfree_skb(skb);
  708. while ((skb = skb_dequeue(&self->txq_ultra)) != NULL)
  709. dev_kfree_skb(skb);
  710. /* Free sliding window buffered packets */
  711. while ((skb = skb_dequeue(&self->wx_list)) != NULL)
  712. dev_kfree_skb(skb);
  713. }
  714. /*
  715.  * Function irlap_setspeed (self, speed)
  716.  *
  717.  *    Change the speed of the IrDA port
  718.  *
  719.  */
  720. void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now)
  721. {
  722. struct sk_buff *skb;
  723. IRDA_DEBUG(0, "%s(), setting speed to %dn", __FUNCTION__, speed);
  724. ASSERT(self != NULL, return;);
  725. ASSERT(self->magic == LAP_MAGIC, return;);
  726. self->speed = speed;
  727. /* Change speed now, or just piggyback speed on frames */
  728. if (now) {
  729. /* Send down empty frame to trigger speed change */
  730. skb = dev_alloc_skb(0);
  731. irlap_queue_xmit(self, skb);
  732. }
  733. }
  734. /*
  735.  * Function irlap_init_qos_capabilities (self, qos)
  736.  *
  737.  *    Initialize QoS for this IrLAP session, What we do is to compute the
  738.  *    intersection of the QoS capabilities for the user, driver and for
  739.  *    IrLAP itself. Normally, IrLAP will not specify any values, but it can
  740.  *    be used to restrict certain values.
  741.  */
  742. void irlap_init_qos_capabilities(struct irlap_cb *self,
  743.  struct qos_info *qos_user)
  744. {
  745. ASSERT(self != NULL, return;);
  746. ASSERT(self->magic == LAP_MAGIC, return;);
  747. ASSERT(self->netdev != NULL, return;);
  748. /* Start out with the maximum QoS support possible */
  749. irda_init_max_qos_capabilies(&self->qos_rx);
  750. /* Apply drivers QoS capabilities */
  751. irda_qos_compute_intersection(&self->qos_rx, self->qos_dev);
  752. /*
  753.  *  Check for user supplied QoS parameters. The service user is only 
  754.  *  allowed to supply these values. We check each parameter since the
  755.  *  user may not have set all of them.
  756.  */
  757. if (qos_user) {
  758. IRDA_DEBUG(1, "%s(), Found user specified QoS!n", __FUNCTION__);
  759. if (qos_user->baud_rate.bits)
  760. self->qos_rx.baud_rate.bits &= qos_user->baud_rate.bits;
  761. if (qos_user->max_turn_time.bits)
  762. self->qos_rx.max_turn_time.bits &= qos_user->max_turn_time.bits;
  763. if (qos_user->data_size.bits)
  764. self->qos_rx.data_size.bits &= qos_user->data_size.bits;
  765. if (qos_user->link_disc_time.bits)
  766. self->qos_rx.link_disc_time.bits &= qos_user->link_disc_time.bits;
  767. }
  768. /* Use 500ms in IrLAP for now */
  769. self->qos_rx.max_turn_time.bits &= 0x01;
  770. /* Set data size */
  771. /*self->qos_rx.data_size.bits &= 0x03;*/
  772. irda_qos_bits_to_value(&self->qos_rx);
  773. }
  774. /*
  775.  * Function irlap_apply_default_connection_parameters (void, now)
  776.  *
  777.  *    Use the default connection and transmission parameters
  778.  * 
  779.  */
  780. void irlap_apply_default_connection_parameters(struct irlap_cb *self)
  781. {
  782. IRDA_DEBUG(4, "%s()n", __FUNCTION__);
  783. ASSERT(self != NULL, return;);
  784. ASSERT(self->magic == LAP_MAGIC, return;);
  785. /* xbofs : Default value in NDM */
  786. self->next_bofs   = 12;
  787. self->bofs_count  = 12;
  788. /* NDM Speed is 9600 */
  789. irlap_change_speed(self, 9600, TRUE);
  790. /* Set mbusy when going to NDM state */
  791. irda_device_set_media_busy(self->netdev, TRUE);
  792. /* 
  793.  * Generate random connection address for this session, which must
  794.  * be 7 bits wide and different from 0x00 and 0xfe 
  795.  */
  796. while ((self->caddr == 0x00) || (self->caddr == 0xfe)) {
  797. get_random_bytes(&self->caddr, sizeof(self->caddr));
  798. self->caddr &= 0xfe;
  799. }
  800. /* Use default values until connection has been negitiated */
  801. self->slot_timeout = sysctl_slot_timeout;
  802. self->final_timeout = FINAL_TIMEOUT;
  803. self->poll_timeout = POLL_TIMEOUT;
  804. self->wd_timeout = WD_TIMEOUT;
  805. /* Set some default values */
  806. self->qos_tx.baud_rate.value = 9600;
  807. self->qos_rx.baud_rate.value = 9600;
  808. self->qos_tx.max_turn_time.value = 0;
  809. self->qos_rx.max_turn_time.value = 0;
  810. self->qos_tx.min_turn_time.value = 0;
  811. self->qos_rx.min_turn_time.value = 0;
  812. self->qos_tx.data_size.value = 64;
  813. self->qos_rx.data_size.value = 64;
  814. self->qos_tx.window_size.value = 1;
  815. self->qos_rx.window_size.value = 1;
  816. self->qos_tx.additional_bofs.value = 12;
  817. self->qos_rx.additional_bofs.value = 12;
  818. self->qos_tx.link_disc_time.value = 0;
  819. self->qos_rx.link_disc_time.value = 0;
  820. irlap_flush_all_queues(self);
  821. self->disconnect_pending = FALSE;
  822. self->connect_pending = FALSE;
  823. }
  824. /*
  825.  * Function irlap_apply_connection_parameters (qos, now)
  826.  *
  827.  *    Initialize IrLAP with the negotiated QoS values
  828.  *
  829.  * If 'now' is false, the speed and xbofs will be changed after the next
  830.  * frame is sent.
  831.  * If 'now' is true, the speed and xbofs is changed immediately
  832.  */
  833. void irlap_apply_connection_parameters(struct irlap_cb *self, int now) 
  834. {
  835. IRDA_DEBUG(4, "%s()n", __FUNCTION__);
  836. ASSERT(self != NULL, return;);
  837. ASSERT(self->magic == LAP_MAGIC, return;);
  838. /* Set the negociated xbofs value */
  839. self->next_bofs   = self->qos_tx.additional_bofs.value;
  840. if (now)
  841. self->bofs_count = self->next_bofs;
  842. /* Set the negociated link speed (may need the new xbofs value) */
  843. irlap_change_speed(self, self->qos_tx.baud_rate.value, now);
  844. self->window_size = self->qos_tx.window_size.value;
  845. self->window      = self->qos_tx.window_size.value;
  846. #ifdef CONFIG_IRDA_DYNAMIC_WINDOW
  847. /*
  848.  *  Calculate how many bytes it is possible to transmit before the
  849.  *  link must be turned around
  850.  */
  851. self->line_capacity = 
  852. irlap_max_line_capacity(self->qos_tx.baud_rate.value,
  853. self->qos_tx.max_turn_time.value);
  854. self->bytes_left = self->line_capacity;
  855. #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
  856. /* 
  857.  *  Initialize timeout values, some of the rules are listed on 
  858.  *  page 92 in IrLAP.
  859.  */
  860. ASSERT(self->qos_tx.max_turn_time.value != 0, return;);
  861. ASSERT(self->qos_rx.max_turn_time.value != 0, return;);
  862. /* The poll timeout applies only to the primary station.
  863.  * It defines the maximum time the primary stay in XMIT mode
  864.  * before timeout and turning the link around (sending a RR).
  865.  * Or, this is how much we can keep the pf bit in primary mode.
  866.  * Therefore, it must be lower or equal than our *OWN* max turn around.
  867.  * Jean II */
  868. self->poll_timeout = self->qos_tx.max_turn_time.value * HZ / 1000;
  869. /* The Final timeout applies only to the primary station.
  870.  * It defines the maximum time the primary wait (mostly in RECV mode)
  871.  * for an answer from the secondary station before polling it again.
  872.  * Therefore, it must be greater or equal than our *PARTNER*
  873.  * max turn around time - Jean II */
  874. self->final_timeout = self->qos_rx.max_turn_time.value * HZ / 1000;
  875. /* The Watchdog Bit timeout applies only to the secondary station.
  876.  * It defines the maximum time the secondary wait (mostly in RECV mode)
  877.  * for poll from the primary station before getting annoyed.
  878.  * Therefore, it must be greater or equal than our *PARTNER*
  879.  * max turn around time - Jean II */
  880. self->wd_timeout = self->final_timeout * 2;
  881. /*
  882.  * N1 and N2 are maximum retry count for *both* the final timer
  883.  * and the wd timer (with a factor 2) as defined above.
  884.  * After N1 retry of a timer, we give a warning to the user.
  885.  * After N2 retry, we consider the link dead and disconnect it.
  886.  * Jean II
  887.  */
  888. /*
  889.  *  Set N1 to 0 if Link Disconnect/Threshold Time = 3 and set it to 
  890.  *  3 seconds otherwise. See page 71 in IrLAP for more details.
  891.  *  Actually, it's not always 3 seconds, as we allow to set
  892.  *  it via sysctl... Max maxtt is 500ms, and N1 need to be multiple
  893.  *  of 2, so 1 second is minimum we can allow. - Jean II
  894.  */
  895. if (self->qos_tx.link_disc_time.value == sysctl_warn_noreply_time)
  896. /* 
  897.  * If we set N1 to 0, it will trigger immediately, which is
  898.  * not what we want. What we really want is to disable it,
  899.  * Jean II 
  900.  */
  901. self->N1 = -2; /* Disable - Need to be multiple of 2*/
  902. else
  903. self->N1 = sysctl_warn_noreply_time * 1000 /
  904.   self->qos_rx.max_turn_time.value;
  905. IRDA_DEBUG(4, "Setting N1 = %dn", self->N1);
  906. /* Set N2 to match our own disconnect time */
  907. self->N2 = self->qos_tx.link_disc_time.value * 1000 / 
  908. self->qos_rx.max_turn_time.value;
  909. IRDA_DEBUG(4, "Setting N2 = %dn", self->N2);
  910. }
  911. #ifdef CONFIG_PROC_FS
  912. /*
  913.  * Function irlap_proc_read (buf, start, offset, len, unused)
  914.  *
  915.  *    Give some info to the /proc file system
  916.  *
  917.  */
  918. int irlap_proc_read(char *buf, char **start, off_t offset, int len)
  919. {
  920. struct irlap_cb *self;
  921. unsigned long flags;
  922. int i = 0;
  923.      
  924. save_flags(flags);
  925. cli();
  926. len = 0;
  927. self = (struct irlap_cb *) hashbin_get_first(irlap);
  928. while (self != NULL) {
  929. ASSERT(self != NULL, return -ENODEV;);
  930. ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
  931. len += sprintf(buf+len, "irlap%d ", i++);
  932. len += sprintf(buf+len, "state: %sn", 
  933.        irlap_state[self->state]);
  934. len += sprintf(buf+len, "  device name: %s, ",
  935.        (self->netdev) ? self->netdev->name : "bug");
  936. len += sprintf(buf+len, "hardware name: %sn", self->hw_name);
  937. len += sprintf(buf+len, "  caddr: %#02x, ", self->caddr);
  938. len += sprintf(buf+len, "saddr: %#08x, ", self->saddr);
  939. len += sprintf(buf+len, "daddr: %#08xn", self->daddr);
  940. len += sprintf(buf+len, "  win size: %d, ", 
  941.        self->window_size);
  942. len += sprintf(buf+len, "win: %d, ", self->window);
  943. #if CONFIG_IRDA_DYNAMIC_WINDOW
  944. len += sprintf(buf+len, "line capacity: %d, ", 
  945.        self->line_capacity);
  946. len += sprintf(buf+len, "bytes left: %dn", self->bytes_left);
  947. #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
  948. len += sprintf(buf+len, "  tx queue len: %d ", 
  949.        skb_queue_len(&self->txq));
  950. len += sprintf(buf+len, "win queue len: %d ", 
  951.        skb_queue_len(&self->wx_list));
  952. len += sprintf(buf+len, "rbusy: %s", self->remote_busy ?
  953.        "TRUE" : "FALSE");
  954. len += sprintf(buf+len, " mbusy: %sn", self->media_busy ?
  955.        "TRUE" : "FALSE");
  956. len += sprintf(buf+len, "  retrans: %d ", self->retry_count);
  957. len += sprintf(buf+len, "vs: %d ", self->vs);
  958. len += sprintf(buf+len, "vr: %d ", self->vr);
  959. len += sprintf(buf+len, "va: %dn", self->va);
  960. len += sprintf(buf+len, "  qostbpstmaxtttdsizetwinsizetaddbofstmintttldisctcompn");
  961. len += sprintf(buf+len, "  txt%dt", 
  962.        self->qos_tx.baud_rate.value);
  963. len += sprintf(buf+len, "%dt", 
  964.        self->qos_tx.max_turn_time.value);
  965. len += sprintf(buf+len, "%dt",
  966.        self->qos_tx.data_size.value);
  967. len += sprintf(buf+len, "%dt",
  968.        self->qos_tx.window_size.value);
  969. len += sprintf(buf+len, "%dt",
  970.        self->qos_tx.additional_bofs.value);
  971. len += sprintf(buf+len, "%dt", 
  972.        self->qos_tx.min_turn_time.value);
  973. len += sprintf(buf+len, "%dt", 
  974.        self->qos_tx.link_disc_time.value);
  975. len += sprintf(buf+len, "n");
  976. len += sprintf(buf+len, "  rxt%dt", 
  977.        self->qos_rx.baud_rate.value);
  978. len += sprintf(buf+len, "%dt", 
  979.        self->qos_rx.max_turn_time.value);
  980. len += sprintf(buf+len, "%dt",
  981.        self->qos_rx.data_size.value);
  982. len += sprintf(buf+len, "%dt",
  983.        self->qos_rx.window_size.value);
  984. len += sprintf(buf+len, "%dt",
  985.        self->qos_rx.additional_bofs.value);
  986. len += sprintf(buf+len, "%dt", 
  987.        self->qos_rx.min_turn_time.value);
  988. len += sprintf(buf+len, "%dt", 
  989.        self->qos_rx.link_disc_time.value);
  990. len += sprintf(buf+len, "n");
  991. self = (struct irlap_cb *) hashbin_get_next(irlap);
  992. }
  993. restore_flags(flags);
  994. return len;
  995. }
  996. #endif /* CONFIG_PROC_FS */