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