c21b4a8bdc736045193ce600f9b7fd4622ab77a9
[linux-flexiantxendom0-3.2.10.git] / net / irda / irlan / irlan_common.c
1 /*********************************************************************
2  *                
3  * Filename:      irlan_common.c
4  * Version:       0.9
5  * Description:   IrDA LAN Access Protocol Implementation
6  * Status:        Experimental.
7  * Author:        Dag Brattli <dagb@cs.uit.no>
8  * Created at:    Sun Aug 31 20:14:37 1997
9  * Modified at:   Sun Dec 26 21:53:10 1999
10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
11  * 
12  *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 
13  *     All Rights Reserved.
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  *     Neither Dag Brattli nor University of Tromsø admit liability nor
21  *     provide warranty for any of this software. This material is 
22  *     provided "AS-IS" and at no charge.
23  *
24  ********************************************************************/
25
26 #include <linux/config.h>
27 #include <linux/module.h>
28
29 #include <linux/kernel.h>
30 #include <linux/string.h>
31 #include <linux/init.h>
32 #include <linux/errno.h>
33 #include <linux/proc_fs.h>
34 #include <linux/seq_file.h>
35 #include <linux/netdevice.h>
36 #include <linux/etherdevice.h>
37 #include <linux/rtnetlink.h>
38
39 #include <asm/system.h>
40 #include <asm/bitops.h>
41 #include <asm/byteorder.h>
42
43 #include <net/irda/irda.h>
44 #include <net/irda/irttp.h>
45 #include <net/irda/irlmp.h>
46 #include <net/irda/iriap.h>
47 #include <net/irda/timer.h>
48
49 #include <net/irda/irlan_common.h>
50 #include <net/irda/irlan_client.h>
51 #include <net/irda/irlan_provider.h> 
52 #include <net/irda/irlan_eth.h>
53 #include <net/irda/irlan_filter.h>
54
55
56 /* 
57  * Send gratuitous ARP when connected to a new AP or not. May be a clever
58  * thing to do, but for some reason the machine crashes if you use DHCP. So
59  * lets not use it by default.
60  */
61 #undef CONFIG_IRLAN_SEND_GRATUITOUS_ARP
62
63 /* extern char sysctl_devname[]; */
64
65 /*
66  *  Master structure
67  */
68 static LIST_HEAD(irlans);
69
70 static void *ckey;
71 static void *skey;
72
73 /* Module parameters */
74 static int eth;   /* Use "eth" or "irlan" name for devices */
75 static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */
76
77 #ifdef CONFIG_PROC_FS
78 static char *irlan_access[] = {
79         "UNKNOWN",
80         "DIRECT",
81         "PEER",
82         "HOSTED"
83 };
84
85 static char *irlan_media[] = {
86         "UNKNOWN",
87         "802.3",
88         "802.5"
89 };
90
91 extern struct proc_dir_entry *proc_irda;
92
93 static int irlan_seq_open(struct inode *inode, struct file *file);
94
95 static struct file_operations irlan_fops = {
96         .owner   = THIS_MODULE,
97         .open    = irlan_seq_open,
98         .read    = seq_read,
99         .llseek  = seq_lseek,
100         .release = seq_release,
101 };
102
103 extern struct proc_dir_entry *proc_irda;
104 #endif /* CONFIG_PROC_FS */
105
106 static void __irlan_close(struct irlan_cb *self);
107 static int __irlan_insert_param(struct sk_buff *skb, char *param, int type, 
108                                 __u8 value_byte, __u16 value_short, 
109                                 __u8 *value_array, __u16 value_len);
110 void irlan_close_tsaps(struct irlan_cb *self);
111
112 /*
113  * Function irlan_init (void)
114  *
115  *    Initialize IrLAN layer
116  *
117  */
118 int __init irlan_init(void)
119 {
120         struct irlan_cb *new;
121         __u16 hints;
122
123         IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
124
125 #ifdef CONFIG_PROC_FS
126         { struct proc_dir_entry *proc;
127         proc = create_proc_entry("irlan", 0, proc_irda);
128         if (!proc) {
129                 printk(KERN_ERR "irlan_init: can't create /proc entry!\n");
130                 return -ENODEV;
131         }
132
133         proc->proc_fops = &irlan_fops;
134         }
135 #endif /* CONFIG_PROC_FS */
136
137         IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
138         hints = irlmp_service_to_hint(S_LAN);
139
140         /* Register with IrLMP as a client */
141         ckey = irlmp_register_client(hints, &irlan_client_discovery_indication,
142                                      NULL, NULL);
143         
144         /* Register with IrLMP as a service */
145         skey = irlmp_register_service(hints);
146
147         /* Start the master IrLAN instance (the only one for now) */
148         new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY);
149
150         /* The master will only open its (listen) control TSAP */
151         irlan_provider_open_ctrl_tsap(new);
152
153         /* Do some fast discovery! */
154         irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
155
156         return 0;
157 }
158
159 void __exit irlan_cleanup(void) 
160 {
161         struct irlan_cb *self, *next;
162
163         IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
164
165         irlmp_unregister_client(ckey);
166         irlmp_unregister_service(skey);
167
168 #ifdef CONFIG_PROC_FS
169         remove_proc_entry("irlan", proc_irda);
170 #endif /* CONFIG_PROC_FS */
171
172         /* Cleanup any leftover network devices */
173         rtnl_lock();
174         list_for_each_entry_safe(self, next, &irlans, dev_list) {
175                 __irlan_close(self);
176         }
177         rtnl_unlock();
178 }
179
180 /*
181  * Function irlan_open (void)
182  *
183  *    Open new instance of a client/provider, we should only register the 
184  *    network device if this instance is ment for a particular client/provider
185  */
186 struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
187 {
188         struct net_device *dev;
189         struct irlan_cb *self;
190
191         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
192
193         /* Create network device with irlan */
194         dev = alloc_netdev(sizeof(*self), 
195                            eth ? "eth%d" : "irlan%d", 
196                            irlan_eth_setup);
197         if (!dev)
198                 return NULL;
199
200         self = dev->priv;
201         self->dev = dev;
202
203         /*
204          *  Initialize local device structure
205          */
206         self->magic = IRLAN_MAGIC;
207         self->saddr = saddr;
208         self->daddr = daddr;
209
210         /* Provider access can only be PEER, DIRECT, or HOSTED */
211         self->provider.access_type = access;
212         self->media = MEDIA_802_3;
213         self->disconnect_reason = LM_USER_REQUEST;
214         init_timer(&self->watchdog_timer);
215         init_timer(&self->client.kick_timer);
216         init_waitqueue_head(&self->open_wait);  
217         
218         skb_queue_head_init(&self->client.txq);
219         
220         irlan_next_client_state(self, IRLAN_IDLE);
221         irlan_next_provider_state(self, IRLAN_IDLE);
222
223         if (register_netdev(dev)) {
224                 IRDA_DEBUG(2, "%s(), register_netdev() failed!\n", 
225                            __FUNCTION__ );
226                 self = NULL;
227                 kfree(dev);
228         } else {
229                 rtnl_lock();
230                 list_add_rcu(&self->dev_list, &irlans);
231                 rtnl_unlock();
232         }
233
234         return self;
235 }
236 /*
237  * Function __irlan_close (self)
238  *
239  *    This function closes and deallocates the IrLAN client instances. Be 
240  *    aware that other functions which calls client_close() must
241  *    remove self from irlans list first.
242  */
243 static void __irlan_close(struct irlan_cb *self)
244 {
245         struct sk_buff *skb;
246
247         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
248         
249         ASSERT_RTNL();
250         ASSERT(self != NULL, return;);
251         ASSERT(self->magic == IRLAN_MAGIC, return;);
252
253         del_timer(&self->watchdog_timer);
254         del_timer(&self->client.kick_timer);
255
256         /* Close all open connections and remove TSAPs */
257         irlan_close_tsaps(self);
258         
259         if (self->client.iriap) 
260                 iriap_close(self->client.iriap);
261
262         /* Remove frames queued on the control channel */
263         while ((skb = skb_dequeue(&self->client.txq)))
264                 dev_kfree_skb(skb);
265
266         /* Unregister and free self via destructor */
267         unregister_netdevice(self->dev);
268 }
269
270 /* Find any instance of irlan, used for client discovery wakeup */
271 struct irlan_cb *irlan_get_any(void)
272 {
273         struct irlan_cb *self;
274
275         list_for_each_entry_rcu(self, &irlans, dev_list) {
276                 return self;
277         }
278         return NULL;
279 }
280
281 /*
282  * Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb)
283  *
284  *    Here we receive the connect indication for the data channel
285  *
286  */
287 void irlan_connect_indication(void *instance, void *sap, struct qos_info *qos,
288                               __u32 max_sdu_size, __u8 max_header_size, 
289                               struct sk_buff *skb)
290 {
291         struct irlan_cb *self;
292         struct tsap_cb *tsap;
293
294         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
295         
296         self = (struct irlan_cb *) instance;
297         tsap = (struct tsap_cb *) sap;
298         
299         ASSERT(self != NULL, return;);
300         ASSERT(self->magic == IRLAN_MAGIC, return;);
301         ASSERT(tsap == self->tsap_data,return;);
302
303         self->max_sdu_size = max_sdu_size;
304         self->max_header_size = max_header_size;
305
306         IRDA_DEBUG(0, "IrLAN, We are now connected!\n");
307
308         del_timer(&self->watchdog_timer);
309
310         /* If you want to pass the skb to *both* state machines, you will
311          * need to skb_clone() it, so that you don't free it twice.
312          * As the state machines don't need it, git rid of it here...
313          * Jean II */
314         if (skb)
315                 dev_kfree_skb(skb);
316
317         irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
318         irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
319
320         if (self->provider.access_type == ACCESS_PEER) {
321                 /* 
322                  * Data channel is open, so we are now allowed to
323                  * configure the remote filter 
324                  */
325                 irlan_get_unicast_addr(self);
326                 irlan_open_unicast_addr(self);
327         }
328         /* Ready to transfer Ethernet frames (at last) */
329         netif_start_queue(self->dev); /* Clear reason */
330 }
331
332 void irlan_connect_confirm(void *instance, void *sap, struct qos_info *qos, 
333                            __u32 max_sdu_size, __u8 max_header_size, 
334                            struct sk_buff *skb) 
335 {
336         struct irlan_cb *self;
337
338         self = (struct irlan_cb *) instance;
339
340         ASSERT(self != NULL, return;);
341         ASSERT(self->magic == IRLAN_MAGIC, return;);
342
343         self->max_sdu_size = max_sdu_size;
344         self->max_header_size = max_header_size;
345
346         /* TODO: we could set the MTU depending on the max_sdu_size */
347
348         IRDA_DEBUG(2, "IrLAN, We are now connected!\n");
349         del_timer(&self->watchdog_timer);
350
351         /* 
352          * Data channel is open, so we are now allowed to configure the remote
353          * filter 
354          */
355         irlan_get_unicast_addr(self);
356         irlan_open_unicast_addr(self);
357         
358         /* Open broadcast and multicast filter by default */
359         irlan_set_broadcast_filter(self, TRUE);
360         irlan_set_multicast_filter(self, TRUE);
361
362         /* Ready to transfer Ethernet frames */
363         netif_start_queue(self->dev);
364         self->disconnect_reason = 0; /* Clear reason */
365 #ifdef CONFIG_IRLAN_SEND_GRATUITOUS_ARP
366         irlan_eth_send_gratuitous_arp(&self->dev);
367 #endif
368         wake_up_interruptible(&self->open_wait);
369 }
370
371 /*
372  * Function irlan_client_disconnect_indication (handle)
373  *
374  *    Callback function for the IrTTP layer. Indicates a disconnection of
375  *    the specified connection (handle)
376  */
377 void irlan_disconnect_indication(void *instance, void *sap, LM_REASON reason, 
378                                  struct sk_buff *userdata) 
379 {
380         struct irlan_cb *self;
381         struct tsap_cb *tsap;
382
383         IRDA_DEBUG(0, "%s(), reason=%d\n", __FUNCTION__ , reason);
384         
385         self = (struct irlan_cb *) instance;
386         tsap = (struct tsap_cb *) sap;
387
388         ASSERT(self != NULL, return;);
389         ASSERT(self->magic == IRLAN_MAGIC, return;);    
390         ASSERT(tsap != NULL, return;);
391         ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
392         
393         ASSERT(tsap == self->tsap_data, return;);
394
395         IRDA_DEBUG(2, "IrLAN, data channel disconnected by peer!\n");
396
397         /* Save reason so we know if we should try to reconnect or not */
398         self->disconnect_reason = reason;
399         
400         switch (reason) {
401         case LM_USER_REQUEST: /* User request */
402                 IRDA_DEBUG(2, "%s(), User requested\n", __FUNCTION__ );
403                 break;
404         case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
405                 IRDA_DEBUG(2, "%s(), Unexpected IrLAP disconnect\n", __FUNCTION__ );
406                 break;
407         case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */
408                 IRDA_DEBUG(2, "%s(), IrLAP connect failed\n", __FUNCTION__ );
409                 break;
410         case LM_LAP_RESET:  /* IrLAP reset */
411                 IRDA_DEBUG(2, "%s(), IrLAP reset\n", __FUNCTION__ );
412                 break;
413         case LM_INIT_DISCONNECT:
414                 IRDA_DEBUG(2, "%s(), IrLMP connect failed\n", __FUNCTION__ );
415                 break;
416         default:
417                 ERROR("%s(), Unknown disconnect reason\n", __FUNCTION__);
418                 break;
419         }
420         
421         /* If you want to pass the skb to *both* state machines, you will
422          * need to skb_clone() it, so that you don't free it twice.
423          * As the state machines don't need it, git rid of it here...
424          * Jean II */
425         if (userdata)
426                 dev_kfree_skb(userdata);
427
428         irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
429         irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
430         
431         wake_up_interruptible(&self->open_wait);
432 }
433
434 void irlan_open_data_tsap(struct irlan_cb *self)
435 {
436         struct tsap_cb *tsap;
437         notify_t notify;
438
439         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
440
441         ASSERT(self != NULL, return;);
442         ASSERT(self->magic == IRLAN_MAGIC, return;);
443
444         /* Check if already open */
445         if (self->tsap_data)
446                 return;
447
448         irda_notify_init(&notify);
449         
450         notify.data_indication       = irlan_eth_receive;
451         notify.udata_indication      = irlan_eth_receive;
452         notify.connect_indication    = irlan_connect_indication;
453         notify.connect_confirm       = irlan_connect_confirm;
454         /*notify.flow_indication       = irlan_eth_flow_indication;*/
455         notify.disconnect_indication = irlan_disconnect_indication;
456         notify.instance              = self;
457         strlcpy(notify.name, "IrLAN data", sizeof(notify.name));
458
459         tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
460         if (!tsap) {
461                 IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ );
462                 return;
463         }
464         self->tsap_data = tsap;
465
466         /* 
467          *  This is the data TSAP selector which we will pass to the client
468          *  when the client ask for it.
469          */
470         self->stsap_sel_data = self->tsap_data->stsap_sel;
471 }
472
473 void irlan_close_tsaps(struct irlan_cb *self)
474 {
475         IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
476
477         ASSERT(self != NULL, return;);
478         ASSERT(self->magic == IRLAN_MAGIC, return;);
479
480         /* Disconnect and close all open TSAP connections */
481         if (self->tsap_data) {
482                 irttp_disconnect_request(self->tsap_data, NULL, P_NORMAL);
483                 irttp_close_tsap(self->tsap_data);
484                 self->tsap_data = NULL;
485         }
486         if (self->client.tsap_ctrl) {
487                 irttp_disconnect_request(self->client.tsap_ctrl, NULL, 
488                                          P_NORMAL);
489                 irttp_close_tsap(self->client.tsap_ctrl);
490                 self->client.tsap_ctrl = NULL;
491         }
492         if (self->provider.tsap_ctrl) {
493                 irttp_disconnect_request(self->provider.tsap_ctrl, NULL, 
494                                          P_NORMAL);
495                 irttp_close_tsap(self->provider.tsap_ctrl);
496                 self->provider.tsap_ctrl = NULL;
497         }
498         self->disconnect_reason = LM_USER_REQUEST;
499 }
500
501 /*
502  * Function irlan_ias_register (self, tsap_sel)
503  *
504  *    Register with LM-IAS
505  *
506  */
507 void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel)
508 {
509         struct ias_object *obj;
510         struct ias_value *new_value;
511
512         ASSERT(self != NULL, return;);
513         ASSERT(self->magic == IRLAN_MAGIC, return;);
514         
515         /* 
516          * Check if object has already been registered by a previous provider.
517          * If that is the case, we just change the value of the attribute
518          */
519         if (!irias_find_object("IrLAN")) {
520                 obj = irias_new_object("IrLAN", IAS_IRLAN_ID);
521                 irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel,
522                                          IAS_KERNEL_ATTR);
523                 irias_insert_object(obj);
524         } else {
525                 new_value = irias_new_integer_value(tsap_sel);
526                 irias_object_change_attribute("IrLAN", "IrDA:TinyTP:LsapSel",
527                                               new_value);
528         }
529         
530         /* Register PnP object only if not registered before */
531         if (!irias_find_object("PnP")) {
532                 obj = irias_new_object("PnP", IAS_PNP_ID);
533 #if 0
534                 irias_add_string_attrib(obj, "Name", sysctl_devname,
535                                         IAS_KERNEL_ATTR);
536 #else
537                 irias_add_string_attrib(obj, "Name", "Linux", IAS_KERNEL_ATTR);
538 #endif
539                 irias_add_string_attrib(obj, "DeviceID", "HWP19F0",
540                                         IAS_KERNEL_ATTR);
541                 irias_add_integer_attrib(obj, "CompCnt", 1, IAS_KERNEL_ATTR);
542                 if (self->provider.access_type == ACCESS_PEER)
543                         irias_add_string_attrib(obj, "Comp#01", "PNP8389",
544                                                 IAS_KERNEL_ATTR);
545                 else
546                         irias_add_string_attrib(obj, "Comp#01", "PNP8294",
547                                                 IAS_KERNEL_ATTR);
548
549                 irias_add_string_attrib(obj, "Manufacturer",
550                                         "Linux-IrDA Project", IAS_KERNEL_ATTR);
551                 irias_insert_object(obj);
552         }
553 }
554
555 /*
556  * Function irlan_run_ctrl_tx_queue (self)
557  *
558  *    Try to send the next command in the control transmit queue
559  *
560  */
561 int irlan_run_ctrl_tx_queue(struct irlan_cb *self)
562 {
563         struct sk_buff *skb;
564
565         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
566
567         if (irda_lock(&self->client.tx_busy) == FALSE)
568                 return -EBUSY;
569
570         skb = skb_dequeue(&self->client.txq);
571         if (!skb) {
572                 self->client.tx_busy = FALSE;
573                 return 0;
574         }
575         
576         /* Check that it's really possible to send commands */
577         if ((self->client.tsap_ctrl == NULL) || 
578             (self->client.state == IRLAN_IDLE)) 
579         {
580                 self->client.tx_busy = FALSE;
581                 dev_kfree_skb(skb);
582                 return -1;
583         }
584         IRDA_DEBUG(2, "%s(), sending ...\n", __FUNCTION__ );
585
586         return irttp_data_request(self->client.tsap_ctrl, skb);
587 }
588
589 /*
590  * Function irlan_ctrl_data_request (self, skb)
591  *
592  *    This function makes sure that commands on the control channel is being
593  *    sent in a command/response fashion
594  */
595 void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
596 {
597         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
598
599         /* Queue command */
600         skb_queue_tail(&self->client.txq, skb);
601
602         /* Try to send command */
603         irlan_run_ctrl_tx_queue(self);
604 }
605
606 /*
607  * Function irlan_get_provider_info (self)
608  *
609  *    Send Get Provider Information command to peer IrLAN layer
610  *
611  */
612 void irlan_get_provider_info(struct irlan_cb *self)
613 {
614         struct sk_buff *skb;
615         __u8 *frame;
616
617         IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
618         
619         ASSERT(self != NULL, return;);
620         ASSERT(self->magic == IRLAN_MAGIC, return;);
621
622         skb = dev_alloc_skb(64);
623         if (!skb)
624                 return;
625
626         /* Reserve space for TTP, LMP, and LAP header */
627         skb_reserve(skb, self->client.max_header_size);
628         skb_put(skb, 2);
629         
630         frame = skb->data;
631         
632         frame[0] = CMD_GET_PROVIDER_INFO;
633         frame[1] = 0x00;                 /* Zero parameters */
634         
635         irlan_ctrl_data_request(self, skb);
636 }
637
638 /*
639  * Function irlan_open_data_channel (self)
640  *
641  *    Send an Open Data Command to provider
642  *
643  */
644 void irlan_open_data_channel(struct irlan_cb *self) 
645 {
646         struct sk_buff *skb;
647         __u8 *frame;
648         
649         IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
650
651         ASSERT(self != NULL, return;);
652         ASSERT(self->magic == IRLAN_MAGIC, return;);
653         
654         skb = dev_alloc_skb(64);
655         if (!skb)
656                 return;
657
658         skb_reserve(skb, self->client.max_header_size);
659         skb_put(skb, 2);
660         
661         frame = skb->data;
662         
663         /* Build frame */
664         frame[0] = CMD_OPEN_DATA_CHANNEL;
665         frame[1] = 0x02; /* Two parameters */
666
667         irlan_insert_string_param(skb, "MEDIA", "802.3");
668         irlan_insert_string_param(skb, "ACCESS_TYPE", "DIRECT");
669         /* irlan_insert_string_param(skb, "MODE", "UNRELIABLE"); */
670
671 /*      self->use_udata = TRUE; */
672
673         irlan_ctrl_data_request(self, skb);
674 }
675
676 void irlan_close_data_channel(struct irlan_cb *self) 
677 {
678         struct sk_buff *skb;
679         __u8 *frame;
680         
681         IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
682
683         ASSERT(self != NULL, return;);
684         ASSERT(self->magic == IRLAN_MAGIC, return;);
685
686         /* Check if the TSAP is still there */
687         if (self->client.tsap_ctrl == NULL)
688                 return;
689
690         skb = dev_alloc_skb(64);
691         if (!skb)
692                 return;
693
694         skb_reserve(skb, self->client.max_header_size);
695         skb_put(skb, 2);
696         
697         frame = skb->data;
698         
699         /* Build frame */
700         frame[0] = CMD_CLOSE_DATA_CHAN;
701         frame[1] = 0x01; /* Two parameters */
702
703         irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
704
705         irlan_ctrl_data_request(self, skb);
706 }
707
708 /*
709  * Function irlan_open_unicast_addr (self)
710  *
711  *    Make IrLAN provider accept ethernet frames addressed to the unicast 
712  *    address.
713  *
714  */
715 void irlan_open_unicast_addr(struct irlan_cb *self) 
716 {
717         struct sk_buff *skb;
718         __u8 *frame;
719         
720         IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
721
722         ASSERT(self != NULL, return;);
723         ASSERT(self->magic == IRLAN_MAGIC, return;);    
724         
725         skb = dev_alloc_skb(128);
726         if (!skb)
727                 return;
728
729         /* Reserve space for TTP, LMP, and LAP header */
730         skb_reserve(skb, self->max_header_size);
731         skb_put(skb, 2);
732         
733         frame = skb->data;
734         
735         frame[0] = CMD_FILTER_OPERATION;
736         frame[1] = 0x03;                 /* Three parameters */
737         irlan_insert_byte_param(skb, "DATA_CHAN" , self->dtsap_sel_data);
738         irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
739         irlan_insert_string_param(skb, "FILTER_MODE", "FILTER"); 
740         
741         irlan_ctrl_data_request(self, skb);
742 }
743
744 /*
745  * Function irlan_set_broadcast_filter (self, status)
746  *
747  *    Make IrLAN provider accept ethernet frames addressed to the broadcast
748  *    address. Be careful with the use of this one, since there may be a lot
749  *    of broadcast traffic out there. We can still function without this
750  *    one but then _we_ have to initiate all communication with other
751  *    hosts, since ARP request for this host will not be answered.
752  */
753 void irlan_set_broadcast_filter(struct irlan_cb *self, int status) 
754 {
755         struct sk_buff *skb;
756         __u8 *frame;
757         
758         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
759
760         ASSERT(self != NULL, return;);
761         ASSERT(self->magic == IRLAN_MAGIC, return;);
762         
763         skb = dev_alloc_skb(128);
764         if (!skb)
765                 return;
766
767         /* Reserve space for TTP, LMP, and LAP header */
768         skb_reserve(skb, self->client.max_header_size);
769         skb_put(skb, 2);
770         
771         frame = skb->data;
772         
773         frame[0] = CMD_FILTER_OPERATION;
774         frame[1] = 0x03;                 /* Three parameters */
775         irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
776         irlan_insert_string_param(skb, "FILTER_TYPE", "BROADCAST");
777         if (status)
778                 irlan_insert_string_param(skb, "FILTER_MODE", "FILTER"); 
779         else
780                 irlan_insert_string_param(skb, "FILTER_MODE", "NONE"); 
781
782         irlan_ctrl_data_request(self, skb);
783 }
784
785 /*
786  * Function irlan_set_multicast_filter (self, status)
787  *
788  *    Make IrLAN provider accept ethernet frames addressed to the multicast
789  *    address. 
790  *
791  */
792 void irlan_set_multicast_filter(struct irlan_cb *self, int status) 
793 {
794         struct sk_buff *skb;
795         __u8 *frame;
796         
797         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
798
799         ASSERT(self != NULL, return;);
800         ASSERT(self->magic == IRLAN_MAGIC, return;);
801
802         skb = dev_alloc_skb(128);
803         if (!skb)
804                 return;
805         
806         /* Reserve space for TTP, LMP, and LAP header */
807         skb_reserve(skb, self->client.max_header_size);
808         skb_put(skb, 2);
809         
810         frame = skb->data;
811         
812         frame[0] = CMD_FILTER_OPERATION;
813         frame[1] = 0x03;                 /* Three parameters */
814         irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
815         irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST");
816         if (status)
817                 irlan_insert_string_param(skb, "FILTER_MODE", "ALL"); 
818         else
819                 irlan_insert_string_param(skb, "FILTER_MODE", "NONE"); 
820
821         irlan_ctrl_data_request(self, skb);
822 }
823
824 /*
825  * Function irlan_get_unicast_addr (self)
826  *
827  *    Retrieves the unicast address from the IrLAN provider. This address
828  *    will be inserted into the devices structure, so the ethernet layer
829  *    can construct its packets.
830  *
831  */
832 void irlan_get_unicast_addr(struct irlan_cb *self) 
833 {
834         struct sk_buff *skb;
835         __u8 *frame;
836                 
837         IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
838
839         ASSERT(self != NULL, return;);
840         ASSERT(self->magic == IRLAN_MAGIC, return;);
841         
842         skb = dev_alloc_skb(128);
843         if (!skb)
844                 return;
845
846         /* Reserve space for TTP, LMP, and LAP header */
847         skb_reserve(skb, self->client.max_header_size);
848         skb_put(skb, 2);
849         
850         frame = skb->data;
851         
852         frame[0] = CMD_FILTER_OPERATION;
853         frame[1] = 0x03;                 /* Three parameters */
854         irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
855         irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
856         irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC"); 
857         
858         irlan_ctrl_data_request(self, skb);
859 }
860
861 /*
862  * Function irlan_get_media_char (self)
863  *
864  *    
865  *
866  */
867 void irlan_get_media_char(struct irlan_cb *self) 
868 {
869         struct sk_buff *skb;
870         __u8 *frame;
871         
872         IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
873
874         ASSERT(self != NULL, return;);
875         ASSERT(self->magic == IRLAN_MAGIC, return;);
876         
877         skb = dev_alloc_skb(64);
878         if (!skb)
879                 return;
880
881         /* Reserve space for TTP, LMP, and LAP header */
882         skb_reserve(skb, self->client.max_header_size);
883         skb_put(skb, 2);
884         
885         frame = skb->data;
886         
887         /* Build frame */
888         frame[0] = CMD_GET_MEDIA_CHAR;
889         frame[1] = 0x01; /* One parameter */
890         
891         irlan_insert_string_param(skb, "MEDIA", "802.3");
892         irlan_ctrl_data_request(self, skb);
893 }
894
895 /*
896  * Function insert_byte_param (skb, param, value)
897  *
898  *    Insert byte parameter into frame
899  *
900  */
901 int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value)
902 {
903         return __irlan_insert_param(skb, param, IRLAN_BYTE, value, 0, NULL, 0);
904 }
905
906 int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value)
907 {
908         return __irlan_insert_param(skb, param, IRLAN_SHORT, 0, value, NULL, 0);
909 }
910
911 /*
912  * Function insert_string (skb, param, value)
913  *
914  *    Insert string parameter into frame
915  *
916  */
917 int irlan_insert_string_param(struct sk_buff *skb, char *param, char *string)
918 {
919         int string_len = strlen(string);
920
921         return __irlan_insert_param(skb, param, IRLAN_ARRAY, 0, 0, string, 
922                                     string_len);
923 }
924
925 /*
926  * Function insert_array_param(skb, param, value, len_value)
927  *
928  *    Insert array parameter into frame
929  *
930  */
931 int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *array,
932                              __u16 array_len)
933 {
934         return __irlan_insert_param(skb, name, IRLAN_ARRAY, 0, 0, array, 
935                                     array_len);
936 }
937
938 /*
939  * Function insert_param (skb, param, value, byte)
940  *
941  *    Insert parameter at end of buffer, structure of a parameter is:
942  *
943  *    -----------------------------------------------------------------------
944  *    | Name Length[1] | Param Name[1..255] | Val Length[2] | Value[0..1016]|
945  *    -----------------------------------------------------------------------
946  */
947 static int __irlan_insert_param(struct sk_buff *skb, char *param, int type, 
948                                 __u8 value_byte, __u16 value_short, 
949                                 __u8 *value_array, __u16 value_len)
950 {
951         __u8 *frame;
952         __u8 param_len;
953         __u16 tmp_le; /* Temporary value in little endian format */
954         int n=0;
955         
956         if (skb == NULL) {
957                 IRDA_DEBUG(2, "%s(), Got NULL skb\n", __FUNCTION__ );
958                 return 0;
959         }       
960
961         param_len = strlen(param);
962         switch (type) {
963         case IRLAN_BYTE:
964                 value_len = 1;
965                 break;
966         case IRLAN_SHORT:
967                 value_len = 2;
968                 break;
969         case IRLAN_ARRAY:
970                 ASSERT(value_array != NULL, return 0;);
971                 ASSERT(value_len > 0, return 0;);
972                 break;
973         default:
974                 IRDA_DEBUG(2, "%s(), Unknown parameter type!\n", __FUNCTION__ );
975                 return 0;
976                 break;
977         }
978         
979         /* Insert at end of sk-buffer */
980         frame = skb->tail;
981
982         /* Make space for data */
983         if (skb_tailroom(skb) < (param_len+value_len+3)) {
984                 IRDA_DEBUG(2, "%s(), No more space at end of skb\n", __FUNCTION__ );
985                 return 0;
986         }       
987         skb_put(skb, param_len+value_len+3);
988         
989         /* Insert parameter length */
990         frame[n++] = param_len;
991         
992         /* Insert parameter */
993         memcpy(frame+n, param, param_len); n += param_len;
994         
995         /* Insert value length (2 byte little endian format, LSB first) */
996         tmp_le = cpu_to_le16(value_len);
997         memcpy(frame+n, &tmp_le, 2); n += 2; /* To avoid alignment problems */
998
999         /* Insert value */
1000         switch (type) {
1001         case IRLAN_BYTE:
1002                 frame[n++] = value_byte;
1003                 break;
1004         case IRLAN_SHORT:
1005                 tmp_le = cpu_to_le16(value_short);
1006                 memcpy(frame+n, &tmp_le, 2); n += 2;
1007                 break;
1008         case IRLAN_ARRAY:
1009                 memcpy(frame+n, value_array, value_len); n+=value_len;
1010                 break;
1011         default:
1012                 break;
1013         }
1014         ASSERT(n == (param_len+value_len+3), return 0;);
1015
1016         return param_len+value_len+3;
1017 }
1018
1019 /*
1020  * Function irlan_extract_param (buf, name, value, len)
1021  *
1022  *    Extracts a single parameter name/value pair from buffer and updates
1023  *    the buffer pointer to point to the next name/value pair. 
1024  */
1025 int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
1026 {
1027         __u8 name_len;
1028         __u16 val_len;
1029         int n=0;
1030         
1031         IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
1032         
1033         /* get length of parameter name (1 byte) */
1034         name_len = buf[n++];
1035         
1036         if (name_len > 254) {
1037                 IRDA_DEBUG(2, "%s(), name_len > 254\n", __FUNCTION__ );
1038                 return -RSP_INVALID_COMMAND_FORMAT;
1039         }
1040         
1041         /* get parameter name */
1042         memcpy(name, buf+n, name_len);
1043         name[name_len] = '\0';
1044         n+=name_len;
1045         
1046         /*  
1047          *  Get length of parameter value (2 bytes in little endian 
1048          *  format) 
1049          */
1050         memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */
1051         le16_to_cpus(&val_len); n+=2;
1052         
1053         if (val_len > 1016) {
1054                 IRDA_DEBUG(2, "%s(), parameter length to long\n", __FUNCTION__ );
1055                 return -RSP_INVALID_COMMAND_FORMAT;
1056         }
1057         *len = val_len;
1058
1059         /* get parameter value */
1060         memcpy(value, buf+n, val_len);
1061         value[val_len] = '\0';
1062         n+=val_len;
1063         
1064         IRDA_DEBUG(4, "Parameter: %s ", name); 
1065         IRDA_DEBUG(4, "Value: %s\n", value); 
1066
1067         return n;
1068 }
1069
1070 #ifdef CONFIG_PROC_FS
1071
1072 /*
1073  * Start of reading /proc entries.
1074  * Return entry at pos, 
1075  *      or start_token to indicate print header line
1076  *      or NULL if end of file
1077  */
1078 static void *irlan_seq_start(struct seq_file *seq, loff_t *pos)
1079 {
1080         int i = 1;
1081         struct irlan_cb *self;
1082
1083         rcu_read_lock();
1084         if (*pos == 0)
1085                 return SEQ_START_TOKEN;
1086
1087         list_for_each_entry(self, &irlans, dev_list) {
1088                 if (*pos == i) 
1089                         return self;
1090                 ++i;
1091         }
1092         return NULL;
1093 }
1094
1095 /* Return entry after v, and increment pos */
1096 static void *irlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1097 {
1098         struct list_head *nxt;
1099
1100         ++*pos;
1101         if (v == SEQ_START_TOKEN) 
1102                 nxt = irlans.next;
1103         else
1104                 nxt = ((struct irlan_cb *)v)->dev_list.next;
1105
1106         return (nxt == &irlans) ? NULL 
1107                 : list_entry(nxt, struct irlan_cb, dev_list);
1108 }
1109
1110 /* End of reading /proc file */
1111 static void irlan_seq_stop(struct seq_file *seq, void *v)
1112 {
1113         rcu_read_unlock();
1114 }
1115
1116
1117 /*
1118  * Show one entry in /proc file.
1119  */
1120 static int irlan_seq_show(struct seq_file *seq, void *v)
1121 {
1122         if (v == SEQ_START_TOKEN)
1123                 seq_puts(seq, "IrLAN instances:\n");
1124         else {
1125                 struct irlan_cb *self = v;
1126                 
1127                 ASSERT(self != NULL, return -1;);
1128                 ASSERT(self->magic == IRLAN_MAGIC, return -1;);
1129
1130                 seq_printf(seq,"ifname: %s,\n",
1131                                self->dev->name);
1132                 seq_printf(seq,"client state: %s, ",
1133                                irlan_state[ self->client.state]);
1134                 seq_printf(seq,"provider state: %s,\n",
1135                                irlan_state[ self->provider.state]);
1136                 seq_printf(seq,"saddr: %#08x, ",
1137                                self->saddr);
1138                 seq_printf(seq,"daddr: %#08x\n",
1139                                self->daddr);
1140                 seq_printf(seq,"version: %d.%d,\n",
1141                                self->version[1], self->version[0]);
1142                 seq_printf(seq,"access type: %s\n", 
1143                                irlan_access[self->client.access_type]);
1144                 seq_printf(seq,"media: %s\n", 
1145                                irlan_media[self->media]);
1146                 
1147                 seq_printf(seq,"local filter:\n");
1148                 seq_printf(seq,"remote filter: ");
1149                 irlan_print_filter(seq, self->client.filter_type);
1150                 seq_printf(seq,"tx busy: %s\n", 
1151                                netif_queue_stopped(self->dev) ? "TRUE" : "FALSE");
1152                         
1153                 seq_putc(seq,'\n');
1154         }
1155         return 0;
1156 }
1157
1158 static struct seq_operations irlan_seq_ops = {
1159         .start = irlan_seq_start,
1160         .next  = irlan_seq_next,
1161         .stop  = irlan_seq_stop,
1162         .show  = irlan_seq_show,
1163 };
1164
1165 static int irlan_seq_open(struct inode *inode, struct file *file)
1166 {
1167         return seq_open(file, &irlan_seq_ops);
1168 }
1169 #endif
1170
1171 /*
1172  * Function print_ret_code (code)
1173  *
1174  *    Print return code of request to peer IrLAN layer.
1175  *
1176  */
1177 void print_ret_code(__u8 code) 
1178 {
1179         switch(code) {
1180         case 0:
1181                 printk(KERN_INFO "Success\n");
1182                 break;
1183         case 1:
1184                 WARNING("IrLAN: Insufficient resources\n");
1185                 break;
1186         case 2:
1187                 WARNING("IrLAN: Invalid command format\n");
1188                 break;
1189         case 3:
1190                 WARNING("IrLAN: Command not supported\n");
1191                 break;
1192         case 4:
1193                 WARNING("IrLAN: Parameter not supported\n");
1194                 break;
1195         case 5:
1196                 WARNING("IrLAN: Value not supported\n");
1197                 break;
1198         case 6:
1199                 WARNING("IrLAN: Not open\n");
1200                 break;
1201         case 7:
1202                 WARNING("IrLAN: Authentication required\n");
1203                 break;
1204         case 8:
1205                 WARNING("IrLAN: Invalid password\n");
1206                 break;
1207         case 9:
1208                 WARNING("IrLAN: Protocol error\n");
1209                 break;
1210         case 255:
1211                 WARNING("IrLAN: Asynchronous status\n");
1212                 break;
1213         }
1214 }
1215
1216 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
1217 MODULE_DESCRIPTION("The Linux IrDA LAN protocol"); 
1218 MODULE_LICENSE("GPL");
1219
1220 MODULE_PARM(eth, "i");
1221 MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)");
1222 MODULE_PARM(access, "i");
1223 MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3");
1224
1225 /*
1226  * Function init_module (void)
1227  *
1228  *    Initialize the IrLAN module, this function is called by the
1229  *    modprobe(1) program.
1230  */
1231 module_init(irlan_init);
1232
1233 /*
1234  * Function cleanup_module (void)
1235  *
1236  *    Remove the IrLAN module, this function is called by the rmmod(1)
1237  *    program
1238  */
1239 module_exit(irlan_cleanup);
1240