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  */
irlan_init(void)120 int __init irlan_init(void)
121 {
122 	struct irlan_cb *new;
123 	__u16 hints;
124 
125 	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
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, "%s()\n", __FUNCTION__);
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 
irlan_cleanup(void)158 void irlan_cleanup(void)
159 {
160 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
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  */
irlan_register_netdev(struct irlan_cb * self)180 int irlan_register_netdev(struct irlan_cb *self)
181 {
182 	int i=0;
183 
184 	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
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, "%s(), register_netdev() failed!\n", __FUNCTION__);
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  */
irlan_open(__u32 saddr,__u32 daddr)207 struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
208 {
209 	struct irlan_cb *self;
210 
211 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
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  */
__irlan_close(struct irlan_cb * self)263 static void __irlan_close(struct irlan_cb *self)
264 {
265 	struct sk_buff *skb;
266 
267 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
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  */
irlan_connect_indication(void * instance,void * sap,struct qos_info * qos,__u32 max_sdu_size,__u8 max_header_size,struct sk_buff * skb)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, "%s()\n", __FUNCTION__);
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 	/* If you want to pass the skb to *both* state machines, you will
321 	 * need to skb_clone() it, so that you don't free it twice.
322 	 * As the state machines don't need it, git rid of it here...
323 	 * Jean II */
324 	if (skb)
325 		dev_kfree_skb(skb);
326 
327 	irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
328 	irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
329 
330 	if (self->provider.access_type == ACCESS_PEER) {
331 		/*
332 		 * Data channel is open, so we are now allowed to
333 		 * configure the remote filter
334 		 */
335 		irlan_get_unicast_addr(self);
336 		irlan_open_unicast_addr(self);
337 	}
338 	/* Ready to transfer Ethernet frames (at last) */
339 	netif_start_queue(&self->dev); /* Clear reason */
340 }
341 
irlan_connect_confirm(void * instance,void * sap,struct qos_info * qos,__u32 max_sdu_size,__u8 max_header_size,struct sk_buff * skb)342 void irlan_connect_confirm(void *instance, void *sap, struct qos_info *qos,
343 			   __u32 max_sdu_size, __u8 max_header_size,
344 			   struct sk_buff *skb)
345 {
346 	struct irlan_cb *self;
347 
348 	self = (struct irlan_cb *) instance;
349 
350 	ASSERT(self != NULL, return;);
351 	ASSERT(self->magic == IRLAN_MAGIC, return;);
352 
353 	self->max_sdu_size = max_sdu_size;
354 	self->max_header_size = max_header_size;
355 
356 	/* TODO: we could set the MTU depending on the max_sdu_size */
357 
358 	IRDA_DEBUG(2, "IrLAN, We are now connected!\n");
359 	del_timer(&self->watchdog_timer);
360 
361 	/*
362 	 * Data channel is open, so we are now allowed to configure the remote
363 	 * filter
364 	 */
365 	irlan_get_unicast_addr(self);
366 	irlan_open_unicast_addr(self);
367 
368 	/* Open broadcast and multicast filter by default */
369  	irlan_set_broadcast_filter(self, TRUE);
370  	irlan_set_multicast_filter(self, TRUE);
371 
372 	/* Ready to transfer Ethernet frames */
373 	netif_start_queue(&self->dev);
374 	self->disconnect_reason = 0; /* Clear reason */
375 #ifdef CONFIG_IRLAN_SEND_GRATUITOUS_ARP
376 	irlan_eth_send_gratuitous_arp(&self->dev);
377 #endif
378 	wake_up_interruptible(&self->open_wait);
379 }
380 
381 /*
382  * Function irlan_client_disconnect_indication (handle)
383  *
384  *    Callback function for the IrTTP layer. Indicates a disconnection of
385  *    the specified connection (handle)
386  */
irlan_disconnect_indication(void * instance,void * sap,LM_REASON reason,struct sk_buff * userdata)387 void irlan_disconnect_indication(void *instance, void *sap, LM_REASON reason,
388 				 struct sk_buff *userdata)
389 {
390 	struct irlan_cb *self;
391 	struct tsap_cb *tsap;
392 
393 	IRDA_DEBUG(0, "%s(), reason=%d\n", __FUNCTION__, reason);
394 
395 	self = (struct irlan_cb *) instance;
396 	tsap = (struct tsap_cb *) sap;
397 
398 	ASSERT(self != NULL, return;);
399 	ASSERT(self->magic == IRLAN_MAGIC, return;);
400 	ASSERT(tsap != NULL, return;);
401 	ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
402 
403 	ASSERT(tsap == self->tsap_data, return;);
404 
405 	IRDA_DEBUG(2, "IrLAN, data channel disconnected by peer!\n");
406 
407 	/* Save reason so we know if we should try to reconnect or not */
408 	self->disconnect_reason = reason;
409 
410 	switch (reason) {
411 	case LM_USER_REQUEST: /* User request */
412 		IRDA_DEBUG(2, "%s(), User requested\n", __FUNCTION__);
413 		break;
414 	case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
415 		IRDA_DEBUG(2, "%s(), Unexpected IrLAP disconnect\n", __FUNCTION__);
416 		break;
417 	case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */
418 		IRDA_DEBUG(2, "%s(), IrLAP connect failed\n", __FUNCTION__);
419 		break;
420 	case LM_LAP_RESET:  /* IrLAP reset */
421 		IRDA_DEBUG(2, "%s(), IrLAP reset\n", __FUNCTION__);
422 		break;
423 	case LM_INIT_DISCONNECT:
424 		IRDA_DEBUG(2, "%s(), IrLMP connect failed\n", __FUNCTION__);
425 		break;
426 	default:
427 		ERROR("%s(), Unknown disconnect reason\n", __FUNCTION__);
428 		break;
429 	}
430 
431 	/* If you want to pass the skb to *both* state machines, you will
432 	 * need to skb_clone() it, so that you don't free it twice.
433 	 * As the state machines don't need it, git rid of it here...
434 	 * Jean II */
435 	if (userdata)
436 		dev_kfree_skb(userdata);
437 
438 	irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
439 	irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
440 
441 	wake_up_interruptible(&self->open_wait);
442 }
443 
irlan_open_data_tsap(struct irlan_cb * self)444 void irlan_open_data_tsap(struct irlan_cb *self)
445 {
446 	struct tsap_cb *tsap;
447 	notify_t notify;
448 
449 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
450 
451 	ASSERT(self != NULL, return;);
452 	ASSERT(self->magic == IRLAN_MAGIC, return;);
453 
454 	/* Check if already open */
455 	if (self->tsap_data)
456 		return;
457 
458 	irda_notify_init(&notify);
459 
460 	notify.data_indication       = irlan_eth_receive;
461 	notify.udata_indication      = irlan_eth_receive;
462 	notify.connect_indication    = irlan_connect_indication;
463 	notify.connect_confirm       = irlan_connect_confirm;
464  	/*notify.flow_indication       = irlan_eth_flow_indication;*/
465 	notify.disconnect_indication = irlan_disconnect_indication;
466 	notify.instance              = self;
467 	strncpy(notify.name, "IrLAN data", NOTIFY_MAX_NAME);
468 
469 	tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
470 	if (!tsap) {
471 		IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__);
472 		return;
473 	}
474 	self->tsap_data = tsap;
475 
476 	/*
477 	 *  This is the data TSAP selector which we will pass to the client
478 	 *  when the client ask for it.
479 	 */
480 	self->stsap_sel_data = self->tsap_data->stsap_sel;
481 }
482 
irlan_close_tsaps(struct irlan_cb * self)483 void irlan_close_tsaps(struct irlan_cb *self)
484 {
485 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
486 
487 	ASSERT(self != NULL, return;);
488 	ASSERT(self->magic == IRLAN_MAGIC, return;);
489 
490 	/* Disconnect and close all open TSAP connections */
491 	if (self->tsap_data) {
492 		irttp_disconnect_request(self->tsap_data, NULL, P_NORMAL);
493 		irttp_close_tsap(self->tsap_data);
494 		self->tsap_data = NULL;
495 	}
496 	if (self->client.tsap_ctrl) {
497 		irttp_disconnect_request(self->client.tsap_ctrl, NULL,
498 					 P_NORMAL);
499 		irttp_close_tsap(self->client.tsap_ctrl);
500 		self->client.tsap_ctrl = NULL;
501 	}
502 	if (self->provider.tsap_ctrl) {
503 		irttp_disconnect_request(self->provider.tsap_ctrl, NULL,
504 					 P_NORMAL);
505 		irttp_close_tsap(self->provider.tsap_ctrl);
506 		self->provider.tsap_ctrl = NULL;
507 	}
508 	self->disconnect_reason = LM_USER_REQUEST;
509 }
510 
511 /*
512  * Function irlan_ias_register (self, tsap_sel)
513  *
514  *    Register with LM-IAS
515  *
516  */
irlan_ias_register(struct irlan_cb * self,__u8 tsap_sel)517 void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel)
518 {
519 	struct ias_object *obj;
520 	struct ias_value *new_value;
521 
522 	ASSERT(self != NULL, return;);
523 	ASSERT(self->magic == IRLAN_MAGIC, return;);
524 
525 	/*
526 	 * Check if object has already been registred by a previous provider.
527 	 * If that is the case, we just change the value of the attribute
528 	 */
529 	if (!irias_find_object("IrLAN")) {
530 		obj = irias_new_object("IrLAN", IAS_IRLAN_ID);
531 		irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel,
532 					 IAS_KERNEL_ATTR);
533 		irias_insert_object(obj);
534 	} else {
535 		new_value = irias_new_integer_value(tsap_sel);
536 		irias_object_change_attribute("IrLAN", "IrDA:TinyTP:LsapSel",
537 					      new_value);
538 	}
539 
540         /* Register PnP object only if not registred before */
541         if (!irias_find_object("PnP")) {
542 		obj = irias_new_object("PnP", IAS_PNP_ID);
543 #if 0
544 		irias_add_string_attrib(obj, "Name", sysctl_devname,
545 					IAS_KERNEL_ATTR);
546 #else
547 		irias_add_string_attrib(obj, "Name", "Linux", IAS_KERNEL_ATTR);
548 #endif
549 		irias_add_string_attrib(obj, "DeviceID", "HWP19F0",
550 					IAS_KERNEL_ATTR);
551 		irias_add_integer_attrib(obj, "CompCnt", 1, IAS_KERNEL_ATTR);
552 		if (self->provider.access_type == ACCESS_PEER)
553 			irias_add_string_attrib(obj, "Comp#01", "PNP8389",
554 						IAS_KERNEL_ATTR);
555 		else
556 			irias_add_string_attrib(obj, "Comp#01", "PNP8294",
557 						IAS_KERNEL_ATTR);
558 
559 		irias_add_string_attrib(obj, "Manufacturer",
560 					"Linux-IrDA Project", IAS_KERNEL_ATTR);
561 		irias_insert_object(obj);
562 	}
563 }
564 
565 /*
566  * Function irlan_run_ctrl_tx_queue (self)
567  *
568  *    Try to send the next command in the control transmit queue
569  *
570  */
irlan_run_ctrl_tx_queue(struct irlan_cb * self)571 int irlan_run_ctrl_tx_queue(struct irlan_cb *self)
572 {
573 	struct sk_buff *skb;
574 
575 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
576 
577 	if (irda_lock(&self->client.tx_busy) == FALSE)
578 		return -EBUSY;
579 
580 	skb = skb_dequeue(&self->client.txq);
581 	if (!skb) {
582 		self->client.tx_busy = FALSE;
583 		return 0;
584 	}
585 
586 	/* Check that it's really possible to send commands */
587 	if ((self->client.tsap_ctrl == NULL) ||
588 	    (self->client.state == IRLAN_IDLE))
589 	{
590 		self->client.tx_busy = FALSE;
591 		dev_kfree_skb(skb);
592 		return -1;
593 	}
594 	IRDA_DEBUG(2, "%s(), sending ...\n", __FUNCTION__);
595 
596 	return irttp_data_request(self->client.tsap_ctrl, skb);
597 }
598 
599 /*
600  * Function irlan_ctrl_data_request (self, skb)
601  *
602  *    This function makes sure that commands on the control channel is being
603  *    sent in a command/response fashion
604  */
irlan_ctrl_data_request(struct irlan_cb * self,struct sk_buff * skb)605 void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
606 {
607 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
608 
609 	/* Queue command */
610 	skb_queue_tail(&self->client.txq, skb);
611 
612 	/* Try to send command */
613 	irlan_run_ctrl_tx_queue(self);
614 }
615 
616 /*
617  * Function irlan_get_provider_info (self)
618  *
619  *    Send Get Provider Information command to peer IrLAN layer
620  *
621  */
irlan_get_provider_info(struct irlan_cb * self)622 void irlan_get_provider_info(struct irlan_cb *self)
623 {
624 	struct sk_buff *skb;
625 	__u8 *frame;
626 
627 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
628 
629 	ASSERT(self != NULL, return;);
630 	ASSERT(self->magic == IRLAN_MAGIC, return;);
631 
632 	skb = dev_alloc_skb(64);
633 	if (!skb)
634 		return;
635 
636 	/* Reserve space for TTP, LMP, and LAP header */
637 	skb_reserve(skb, self->client.max_header_size);
638 	skb_put(skb, 2);
639 
640 	frame = skb->data;
641 
642  	frame[0] = CMD_GET_PROVIDER_INFO;
643 	frame[1] = 0x00;                 /* Zero parameters */
644 
645 	irlan_ctrl_data_request(self, skb);
646 }
647 
648 /*
649  * Function irlan_open_data_channel (self)
650  *
651  *    Send an Open Data Command to provider
652  *
653  */
irlan_open_data_channel(struct irlan_cb * self)654 void irlan_open_data_channel(struct irlan_cb *self)
655 {
656 	struct sk_buff *skb;
657 	__u8 *frame;
658 
659 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
660 
661 	ASSERT(self != NULL, return;);
662 	ASSERT(self->magic == IRLAN_MAGIC, return;);
663 
664 	skb = dev_alloc_skb(64);
665 	if (!skb)
666 		return;
667 
668 	skb_reserve(skb, self->client.max_header_size);
669 	skb_put(skb, 2);
670 
671 	frame = skb->data;
672 
673 	/* Build frame */
674  	frame[0] = CMD_OPEN_DATA_CHANNEL;
675 	frame[1] = 0x02; /* Two parameters */
676 
677 	irlan_insert_string_param(skb, "MEDIA", "802.3");
678 	irlan_insert_string_param(skb, "ACCESS_TYPE", "DIRECT");
679 	/* irlan_insert_string_param(skb, "MODE", "UNRELIABLE"); */
680 
681 /* 	self->use_udata = TRUE; */
682 
683 	irlan_ctrl_data_request(self, skb);
684 }
685 
irlan_close_data_channel(struct irlan_cb * self)686 void irlan_close_data_channel(struct irlan_cb *self)
687 {
688 	struct sk_buff *skb;
689 	__u8 *frame;
690 
691 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
692 
693 	ASSERT(self != NULL, return;);
694 	ASSERT(self->magic == IRLAN_MAGIC, return;);
695 
696 	/* Check if the TSAP is still there */
697 	if (self->client.tsap_ctrl == NULL)
698 		return;
699 
700 	skb = dev_alloc_skb(64);
701 	if (!skb)
702 		return;
703 
704 	skb_reserve(skb, self->client.max_header_size);
705 	skb_put(skb, 2);
706 
707 	frame = skb->data;
708 
709 	/* Build frame */
710  	frame[0] = CMD_CLOSE_DATA_CHAN;
711 	frame[1] = 0x01; /* Two parameters */
712 
713 	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
714 
715 	irlan_ctrl_data_request(self, skb);
716 }
717 
718 /*
719  * Function irlan_open_unicast_addr (self)
720  *
721  *    Make IrLAN provider accept ethernet frames addressed to the unicast
722  *    address.
723  *
724  */
irlan_open_unicast_addr(struct irlan_cb * self)725 void irlan_open_unicast_addr(struct irlan_cb *self)
726 {
727 	struct sk_buff *skb;
728 	__u8 *frame;
729 
730 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
731 
732 	ASSERT(self != NULL, return;);
733 	ASSERT(self->magic == IRLAN_MAGIC, return;);
734 
735 	skb = dev_alloc_skb(128);
736 	if (!skb)
737 		return;
738 
739 	/* Reserve space for TTP, LMP, and LAP header */
740 	skb_reserve(skb, self->max_header_size);
741 	skb_put(skb, 2);
742 
743 	frame = skb->data;
744 
745  	frame[0] = CMD_FILTER_OPERATION;
746 	frame[1] = 0x03;                 /* Three parameters */
747  	irlan_insert_byte_param(skb, "DATA_CHAN" , self->dtsap_sel_data);
748  	irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
749  	irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");
750 
751 	irlan_ctrl_data_request(self, skb);
752 }
753 
754 /*
755  * Function irlan_set_broadcast_filter (self, status)
756  *
757  *    Make IrLAN provider accept ethernet frames addressed to the broadcast
758  *    address. Be careful with the use of this one, since there may be a lot
759  *    of broadcast traffic out there. We can still function without this
760  *    one but then _we_ have to initiate all communication with other
761  *    hosts, since ARP request for this host will not be answered.
762  */
irlan_set_broadcast_filter(struct irlan_cb * self,int status)763 void irlan_set_broadcast_filter(struct irlan_cb *self, int status)
764 {
765 	struct sk_buff *skb;
766 	__u8 *frame;
767 
768 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
769 
770 	ASSERT(self != NULL, return;);
771 	ASSERT(self->magic == IRLAN_MAGIC, return;);
772 
773  	skb = dev_alloc_skb(128);
774 	if (!skb)
775 		return;
776 
777 	/* Reserve space for TTP, LMP, and LAP header */
778 	skb_reserve(skb, self->client.max_header_size);
779 	skb_put(skb, 2);
780 
781 	frame = skb->data;
782 
783  	frame[0] = CMD_FILTER_OPERATION;
784 	frame[1] = 0x03;                 /* Three parameters */
785  	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
786  	irlan_insert_string_param(skb, "FILTER_TYPE", "BROADCAST");
787 	if (status)
788 		irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");
789 	else
790 		irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
791 
792 	irlan_ctrl_data_request(self, skb);
793 }
794 
795 /*
796  * Function irlan_set_multicast_filter (self, status)
797  *
798  *    Make IrLAN provider accept ethernet frames addressed to the multicast
799  *    address.
800  *
801  */
irlan_set_multicast_filter(struct irlan_cb * self,int status)802 void irlan_set_multicast_filter(struct irlan_cb *self, int status)
803 {
804 	struct sk_buff *skb;
805 	__u8 *frame;
806 
807 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
808 
809 	ASSERT(self != NULL, return;);
810 	ASSERT(self->magic == IRLAN_MAGIC, return;);
811 
812  	skb = dev_alloc_skb(128);
813 	if (!skb)
814 		return;
815 
816 	/* Reserve space for TTP, LMP, and LAP header */
817 	skb_reserve(skb, self->client.max_header_size);
818 	skb_put(skb, 2);
819 
820 	frame = skb->data;
821 
822  	frame[0] = CMD_FILTER_OPERATION;
823 	frame[1] = 0x03;                 /* Three parameters */
824  	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
825  	irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST");
826 	if (status)
827 		irlan_insert_string_param(skb, "FILTER_MODE", "ALL");
828 	else
829 		irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
830 
831 	irlan_ctrl_data_request(self, skb);
832 }
833 
834 /*
835  * Function irlan_get_unicast_addr (self)
836  *
837  *    Retrives the unicast address from the IrLAN provider. This address
838  *    will be inserted into the devices structure, so the ethernet layer
839  *    can construct its packets.
840  *
841  */
irlan_get_unicast_addr(struct irlan_cb * self)842 void irlan_get_unicast_addr(struct irlan_cb *self)
843 {
844 	struct sk_buff *skb;
845 	__u8 *frame;
846 
847 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
848 
849 	ASSERT(self != NULL, return;);
850 	ASSERT(self->magic == IRLAN_MAGIC, return;);
851 
852 	skb = dev_alloc_skb(128);
853 	if (!skb)
854 		return;
855 
856 	/* Reserve space for TTP, LMP, and LAP header */
857 	skb_reserve(skb, self->client.max_header_size);
858 	skb_put(skb, 2);
859 
860 	frame = skb->data;
861 
862  	frame[0] = CMD_FILTER_OPERATION;
863 	frame[1] = 0x03;                 /* Three parameters */
864  	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
865  	irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
866  	irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC");
867 
868 	irlan_ctrl_data_request(self, skb);
869 }
870 
871 /*
872  * Function irlan_get_media_char (self)
873  *
874  *
875  *
876  */
irlan_get_media_char(struct irlan_cb * self)877 void irlan_get_media_char(struct irlan_cb *self)
878 {
879 	struct sk_buff *skb;
880 	__u8 *frame;
881 
882 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
883 
884 	ASSERT(self != NULL, return;);
885 	ASSERT(self->magic == IRLAN_MAGIC, return;);
886 
887 	skb = dev_alloc_skb(64);
888 	if (!skb)
889 		return;
890 
891 	/* Reserve space for TTP, LMP, and LAP header */
892 	skb_reserve(skb, self->client.max_header_size);
893 	skb_put(skb, 2);
894 
895 	frame = skb->data;
896 
897 	/* Build frame */
898  	frame[0] = CMD_GET_MEDIA_CHAR;
899 	frame[1] = 0x01; /* One parameter */
900 
901 	irlan_insert_string_param(skb, "MEDIA", "802.3");
902 	irlan_ctrl_data_request(self, skb);
903 }
904 
905 /*
906  * Function insert_byte_param (skb, param, value)
907  *
908  *    Insert byte parameter into frame
909  *
910  */
irlan_insert_byte_param(struct sk_buff * skb,char * param,__u8 value)911 int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value)
912 {
913 	return __irlan_insert_param(skb, param, IRLAN_BYTE, value, 0, NULL, 0);
914 }
915 
irlan_insert_short_param(struct sk_buff * skb,char * param,__u16 value)916 int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value)
917 {
918 	return __irlan_insert_param(skb, param, IRLAN_SHORT, 0, value, NULL, 0);
919 }
920 
921 /*
922  * Function insert_string (skb, param, value)
923  *
924  *    Insert string parameter into frame
925  *
926  */
irlan_insert_string_param(struct sk_buff * skb,char * param,char * string)927 int irlan_insert_string_param(struct sk_buff *skb, char *param, char *string)
928 {
929 	int string_len = strlen(string);
930 
931 	return __irlan_insert_param(skb, param, IRLAN_ARRAY, 0, 0, string,
932 				    string_len);
933 }
934 
935 /*
936  * Function insert_array_param(skb, param, value, len_value)
937  *
938  *    Insert array parameter into frame
939  *
940  */
irlan_insert_array_param(struct sk_buff * skb,char * name,__u8 * array,__u16 array_len)941 int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *array,
942 			     __u16 array_len)
943 {
944 	return __irlan_insert_param(skb, name, IRLAN_ARRAY, 0, 0, array,
945 				    array_len);
946 }
947 
948 /*
949  * Function insert_param (skb, param, value, byte)
950  *
951  *    Insert parameter at end of buffer, structure of a parameter is:
952  *
953  *    -----------------------------------------------------------------------
954  *    | Name Length[1] | Param Name[1..255] | Val Length[2] | Value[0..1016]|
955  *    -----------------------------------------------------------------------
956  */
__irlan_insert_param(struct sk_buff * skb,char * param,int type,__u8 value_byte,__u16 value_short,__u8 * value_array,__u16 value_len)957 static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
958 				__u8 value_byte, __u16 value_short,
959 				__u8 *value_array, __u16 value_len)
960 {
961 	__u8 *frame;
962 	__u8 param_len;
963 	__u16 tmp_le; /* Temporary value in little endian format */
964 	int n=0;
965 
966 	if (skb == NULL) {
967 		IRDA_DEBUG(2, "%s(), Got NULL skb\n", __FUNCTION__);
968 		return 0;
969 	}
970 
971 	param_len = strlen(param);
972 	switch (type) {
973 	case IRLAN_BYTE:
974 		value_len = 1;
975 		break;
976 	case IRLAN_SHORT:
977 		value_len = 2;
978 		break;
979 	case IRLAN_ARRAY:
980 		ASSERT(value_array != NULL, return 0;);
981 		ASSERT(value_len > 0, return 0;);
982 		break;
983 	default:
984 		IRDA_DEBUG(2, "%s(), Unknown parameter type!\n", __FUNCTION__);
985 		return 0;
986 		break;
987 	}
988 
989 	/* Insert at end of sk-buffer */
990 	frame = skb->tail;
991 
992 	/* Make space for data */
993 	if (skb_tailroom(skb) < (param_len+value_len+3)) {
994 		IRDA_DEBUG(2, "%s(), No more space at end of skb\n", __FUNCTION__);
995 		return 0;
996 	}
997 	skb_put(skb, param_len+value_len+3);
998 
999 	/* Insert parameter length */
1000 	frame[n++] = param_len;
1001 
1002 	/* Insert parameter */
1003 	memcpy(frame+n, param, param_len); n += param_len;
1004 
1005 	/* Insert value length (2 byte little endian format, LSB first) */
1006 	tmp_le = cpu_to_le16(value_len);
1007 	memcpy(frame+n, &tmp_le, 2); n += 2; /* To avoid alignment problems */
1008 
1009 	/* Insert value */
1010 	switch (type) {
1011 	case IRLAN_BYTE:
1012 		frame[n++] = value_byte;
1013 		break;
1014 	case IRLAN_SHORT:
1015 		tmp_le = cpu_to_le16(value_short);
1016 		memcpy(frame+n, &tmp_le, 2); n += 2;
1017 		break;
1018 	case IRLAN_ARRAY:
1019 		memcpy(frame+n, value_array, value_len); n+=value_len;
1020 		break;
1021 	default:
1022 		break;
1023 	}
1024 	ASSERT(n == (param_len+value_len+3), return 0;);
1025 
1026 	return param_len+value_len+3;
1027 }
1028 
1029 /*
1030  * Function irlan_extract_param (buf, name, value, len)
1031  *
1032  *    Extracts a single parameter name/value pair from buffer and updates
1033  *    the buffer pointer to point to the next name/value pair.
1034  */
irlan_extract_param(__u8 * buf,char * name,char * value,__u16 * len)1035 int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
1036 {
1037 	__u8 name_len;
1038 	__u16 val_len;
1039 	int n=0;
1040 
1041 	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1042 
1043 	/* get length of parameter name (1 byte) */
1044 	name_len = buf[n++];
1045 
1046 	if (name_len > 254) {
1047 		IRDA_DEBUG(2, "%s(), name_len > 254\n", __FUNCTION__);
1048 		return -RSP_INVALID_COMMAND_FORMAT;
1049 	}
1050 
1051 	/* get parameter name */
1052 	memcpy(name, buf+n, name_len);
1053 	name[name_len] = '\0';
1054 	n+=name_len;
1055 
1056 	/*
1057 	 *  Get length of parameter value (2 bytes in little endian
1058 	 *  format)
1059 	 */
1060 	memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */
1061 	le16_to_cpus(&val_len); n+=2;
1062 
1063 	if (val_len > 1016) {
1064 		IRDA_DEBUG(2, "%s(), parameter length to long\n", __FUNCTION__);
1065 		return -RSP_INVALID_COMMAND_FORMAT;
1066 	}
1067 	*len = val_len;
1068 
1069 	/* get parameter value */
1070 	memcpy(value, buf+n, val_len);
1071 	value[val_len] = '\0';
1072 	n+=val_len;
1073 
1074 	IRDA_DEBUG(4, "Parameter: %s ", name);
1075 	IRDA_DEBUG(4, "Value: %s\n", value);
1076 
1077 	return n;
1078 }
1079 
1080 #ifdef CONFIG_PROC_FS
1081 /*
1082  * Function irlan_client_proc_read (buf, start, offset, len, unused)
1083  *
1084  *    Give some info to the /proc file system
1085  */
irlan_proc_read(char * buf,char ** start,off_t offset,int len)1086 static int irlan_proc_read(char *buf, char **start, off_t offset, int len)
1087 {
1088  	struct irlan_cb *self;
1089 	unsigned long flags;
1090 	ASSERT(irlan != NULL, return 0;);
1091 
1092 	save_flags(flags);
1093 	cli();
1094 
1095 	len = 0;
1096 
1097 	len += sprintf(buf+len, "IrLAN instances:\n");
1098 
1099 	self = (struct irlan_cb *) hashbin_get_first(irlan);
1100 	while (self != NULL) {
1101 		ASSERT(self->magic == IRLAN_MAGIC, break;);
1102 
1103 		len += sprintf(buf+len, "ifname: %s,\n",
1104 			       self->dev.name);
1105 		len += sprintf(buf+len, "client state: %s, ",
1106 			       irlan_state[ self->client.state]);
1107 		len += sprintf(buf+len, "provider state: %s,\n",
1108 			       irlan_state[ self->provider.state]);
1109 		len += sprintf(buf+len, "saddr: %#08x, ",
1110 			       self->saddr);
1111 		len += sprintf(buf+len, "daddr: %#08x\n",
1112 			       self->daddr);
1113 		len += sprintf(buf+len, "version: %d.%d,\n",
1114 			       self->version[1], self->version[0]);
1115 		len += sprintf(buf+len, "access type: %s\n",
1116 			       irlan_access[self->client.access_type]);
1117 		len += sprintf(buf+len, "media: %s\n",
1118 			       irlan_media[self->media]);
1119 
1120 		len += sprintf(buf+len, "local filter:\n");
1121 		len += sprintf(buf+len, "remote filter: ");
1122 		len += irlan_print_filter(self->client.filter_type,
1123 					  buf+len);
1124 
1125 		len += sprintf(buf+len, "tx busy: %s\n",
1126 			       netif_queue_stopped(&self->dev) ? "TRUE" : "FALSE");
1127 
1128 		len += sprintf(buf+len, "\n");
1129 
1130 		self = (struct irlan_cb *) hashbin_get_next(irlan);
1131  	}
1132 	restore_flags(flags);
1133 
1134 	return len;
1135 }
1136 #endif
1137 
1138 /*
1139  * Function print_ret_code (code)
1140  *
1141  *    Print return code of request to peer IrLAN layer.
1142  *
1143  */
print_ret_code(__u8 code)1144 void print_ret_code(__u8 code)
1145 {
1146 	switch(code) {
1147 	case 0:
1148 		printk(KERN_INFO "Success\n");
1149 		break;
1150 	case 1:
1151 		WARNING("IrLAN: Insufficient resources\n");
1152 		break;
1153 	case 2:
1154 		WARNING("IrLAN: Invalid command format\n");
1155 		break;
1156 	case 3:
1157 		WARNING("IrLAN: Command not supported\n");
1158 		break;
1159 	case 4:
1160 		WARNING("IrLAN: Parameter not supported\n");
1161 		break;
1162 	case 5:
1163 		WARNING("IrLAN: Value not supported\n");
1164 		break;
1165 	case 6:
1166 		WARNING("IrLAN: Not open\n");
1167 		break;
1168 	case 7:
1169 		WARNING("IrLAN: Authentication required\n");
1170 		break;
1171 	case 8:
1172 		WARNING("IrLAN: Invalid password\n");
1173 		break;
1174 	case 9:
1175 		WARNING("IrLAN: Protocol error\n");
1176 		break;
1177 	case 255:
1178 		WARNING("IrLAN: Asynchronous status\n");
1179 		break;
1180 	}
1181 }
1182 
irlan_mod_inc_use_count(void)1183 void irlan_mod_inc_use_count(void)
1184 {
1185 #ifdef MODULE
1186 	MOD_INC_USE_COUNT;
1187 #endif
1188 }
1189 
irlan_mod_dec_use_count(void)1190 void irlan_mod_dec_use_count(void)
1191 {
1192 #ifdef MODULE
1193 	MOD_DEC_USE_COUNT;
1194 #endif
1195 }
1196 
1197 #ifdef MODULE
1198 
1199 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
1200 MODULE_DESCRIPTION("The Linux IrDA LAN protocol");
1201 MODULE_LICENSE("GPL");
1202 
1203 MODULE_PARM(eth, "i");
1204 MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)");
1205 MODULE_PARM(access, "i");
1206 MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3");
1207 
1208 /*
1209  * Function init_module (void)
1210  *
1211  *    Initialize the IrLAN module, this function is called by the
1212  *    modprobe(1) program.
1213  */
init_module(void)1214 int init_module(void)
1215 {
1216 	return irlan_init();
1217 }
1218 
1219 /*
1220  * Function cleanup_module (void)
1221  *
1222  *    Remove the IrLAN module, this function is called by the rmmod(1)
1223  *    program
1224  */
cleanup_module(void)1225 void cleanup_module(void)
1226 {
1227 	/* Free some memory */
1228  	irlan_cleanup();
1229 }
1230 
1231 #endif /* MODULE */
1232 
1233