Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / net / irda / irlan / irlan_client.c
1 /*********************************************************************
2  *
3  * Filename:      irlan_client.c
4  * Version:       0.9
5  * Description:   IrDA LAN Access Protocol (IrLAN) Client
6  * Status:        Experimental.
7  * Author:        Dag Brattli <dagb@cs.uit.no>
8  * Created at:    Sun Aug 31 20:14:37 1997
9  * Modified at:   Tue Dec 14 15:47:02 1999
10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
11  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
12  *                slip.c by Laurence Culhane, <loz@holmes.demon.co.uk>
13  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
14  *
15  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
16  *     All Rights Reserved.
17  *
18  *     This program is free software; you can redistribute it and/or
19  *     modify it under the terms of the GNU General Public License as
20  *     published by the Free Software Foundation; either version 2 of
21  *     the License, or (at your option) any later version.
22  *
23  *     Neither Dag Brattli nor University of Tromsø admit liability nor
24  *     provide warranty for any of this software. This material is
25  *     provided "AS-IS" and at no charge.
26  *
27  ********************************************************************/
28
29 #include <linux/kernel.h>
30 #include <linux/string.h>
31 #include <linux/slab.h>
32 #include <linux/errno.h>
33 #include <linux/init.h>
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
36 #include <linux/if_arp.h>
37 #include <linux/bitops.h>
38 #include <net/arp.h>
39
40 #include <asm/byteorder.h>
41
42 #include <net/irda/irda.h>
43 #include <net/irda/irttp.h>
44 #include <net/irda/irlmp.h>
45 #include <net/irda/irias_object.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_event.h>
51 #include <net/irda/irlan_eth.h>
52 #include <net/irda/irlan_provider.h>
53 #include <net/irda/irlan_client.h>
54
55 #undef CONFIG_IRLAN_GRATUITOUS_ARP
56
57 static void irlan_client_ctrl_disconnect_indication(void *instance, void *sap,
58                                                     LM_REASON reason,
59                                                     struct sk_buff *);
60 static int irlan_client_ctrl_data_indication(void *instance, void *sap,
61                                              struct sk_buff *skb);
62 static void irlan_client_ctrl_connect_confirm(void *instance, void *sap,
63                                               struct qos_info *qos,
64                                               __u32 max_sdu_size,
65                                               __u8 max_header_size,
66                                               struct sk_buff *);
67 static void irlan_check_response_param(struct irlan_cb *self, char *param,
68                                        char *value, int val_len);
69 static void irlan_client_open_ctrl_tsap(struct irlan_cb *self);
70
71 static void irlan_client_kick_timer_expired(void *data)
72 {
73         struct irlan_cb *self = (struct irlan_cb *) data;
74
75         IRDA_ASSERT(self != NULL, return;);
76         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
77
78         /*
79          * If we are in peer mode, the client may not have got the discovery
80          * indication it needs to make progress. If the client is still in
81          * IDLE state, we must kick it to, but only if the provider is not IDLE
82          */
83         if ((self->provider.access_type == ACCESS_PEER) &&
84             (self->client.state == IRLAN_IDLE) &&
85             (self->provider.state != IRLAN_IDLE)) {
86                 irlan_client_wakeup(self, self->saddr, self->daddr);
87         }
88 }
89
90 static void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout)
91 {
92         irda_start_timer(&self->client.kick_timer, timeout, (void *) self,
93                          irlan_client_kick_timer_expired);
94 }
95
96 /*
97  * Function irlan_client_wakeup (self, saddr, daddr)
98  *
99  *    Wake up client
100  *
101  */
102 void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr)
103 {
104         IRDA_ASSERT(self != NULL, return;);
105         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
106
107         /*
108          * Check if we are already awake, or if we are a provider in direct
109          * mode (in that case we must leave the client idle
110          */
111         if ((self->client.state != IRLAN_IDLE) ||
112             (self->provider.access_type == ACCESS_DIRECT))
113         {
114                 pr_debug("%s(), already awake!\n", __func__);
115                         return;
116         }
117
118         /* Addresses may have changed! */
119         self->saddr = saddr;
120         self->daddr = daddr;
121
122         if (self->disconnect_reason == LM_USER_REQUEST) {
123                 pr_debug("%s(), still stopped by user\n", __func__);
124                         return;
125         }
126
127         /* Open TSAPs */
128         irlan_client_open_ctrl_tsap(self);
129         irlan_open_data_tsap(self);
130
131         irlan_do_client_event(self, IRLAN_DISCOVERY_INDICATION, NULL);
132
133         /* Start kick timer */
134         irlan_client_start_kick_timer(self, 2*HZ);
135 }
136
137 /*
138  * Function irlan_discovery_indication (daddr)
139  *
140  *    Remote device with IrLAN server support discovered
141  *
142  */
143 void irlan_client_discovery_indication(discinfo_t *discovery,
144                                        DISCOVERY_MODE mode,
145                                        void *priv)
146 {
147         struct irlan_cb *self;
148         __u32 saddr, daddr;
149
150         IRDA_ASSERT(discovery != NULL, return;);
151
152         /*
153          * I didn't check it, but I bet that IrLAN suffer from the same
154          * deficiency as IrComm and doesn't handle two instances
155          * simultaneously connecting to each other.
156          * Same workaround, drop passive discoveries.
157          * Jean II */
158         if(mode == DISCOVERY_PASSIVE)
159                 return;
160
161         saddr = discovery->saddr;
162         daddr = discovery->daddr;
163
164         /* Find instance */
165         rcu_read_lock();
166         self = irlan_get_any();
167         if (self) {
168                 IRDA_ASSERT(self->magic == IRLAN_MAGIC, goto out;);
169
170                 pr_debug("%s(), Found instance (%08x)!\n", __func__ ,
171                          daddr);
172
173                 irlan_client_wakeup(self, saddr, daddr);
174         }
175 IRDA_ASSERT_LABEL(out:)
176         rcu_read_unlock();
177 }
178
179 /*
180  * Function irlan_client_data_indication (handle, skb)
181  *
182  *    This function gets the data that is received on the control channel
183  *
184  */
185 static int irlan_client_ctrl_data_indication(void *instance, void *sap,
186                                              struct sk_buff *skb)
187 {
188         struct irlan_cb *self;
189
190         self = instance;
191
192         IRDA_ASSERT(self != NULL, return -1;);
193         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
194         IRDA_ASSERT(skb != NULL, return -1;);
195
196         irlan_do_client_event(self, IRLAN_DATA_INDICATION, skb);
197
198         /* Ready for a new command */
199         pr_debug("%s(), clearing tx_busy\n", __func__);
200         self->client.tx_busy = FALSE;
201
202         /* Check if we have some queued commands waiting to be sent */
203         irlan_run_ctrl_tx_queue(self);
204
205         return 0;
206 }
207
208 static void irlan_client_ctrl_disconnect_indication(void *instance, void *sap,
209                                                     LM_REASON reason,
210                                                     struct sk_buff *userdata)
211 {
212         struct irlan_cb *self;
213         struct tsap_cb *tsap;
214         struct sk_buff *skb;
215
216         pr_debug("%s(), reason=%d\n", __func__ , reason);
217
218         self = instance;
219         tsap = sap;
220
221         IRDA_ASSERT(self != NULL, return;);
222         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
223         IRDA_ASSERT(tsap != NULL, return;);
224         IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
225
226         IRDA_ASSERT(tsap == self->client.tsap_ctrl, return;);
227
228         /* Remove frames queued on the control channel */
229         while ((skb = skb_dequeue(&self->client.txq)) != NULL) {
230                 dev_kfree_skb(skb);
231         }
232         self->client.tx_busy = FALSE;
233
234         irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
235 }
236
237 /*
238  * Function irlan_client_open_tsaps (self)
239  *
240  *    Initialize callbacks and open IrTTP TSAPs
241  *
242  */
243 static void irlan_client_open_ctrl_tsap(struct irlan_cb *self)
244 {
245         struct tsap_cb *tsap;
246         notify_t notify;
247
248         IRDA_ASSERT(self != NULL, return;);
249         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
250
251         /* Check if already open */
252         if (self->client.tsap_ctrl)
253                 return;
254
255         irda_notify_init(&notify);
256
257         /* Set up callbacks */
258         notify.data_indication       = irlan_client_ctrl_data_indication;
259         notify.connect_confirm       = irlan_client_ctrl_connect_confirm;
260         notify.disconnect_indication = irlan_client_ctrl_disconnect_indication;
261         notify.instance = self;
262         strlcpy(notify.name, "IrLAN ctrl (c)", sizeof(notify.name));
263
264         tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
265         if (!tsap) {
266                 pr_debug("%s(), Got no tsap!\n", __func__);
267                 return;
268         }
269         self->client.tsap_ctrl = tsap;
270 }
271
272 /*
273  * Function irlan_client_connect_confirm (handle, skb)
274  *
275  *    Connection to peer IrLAN laye confirmed
276  *
277  */
278 static void irlan_client_ctrl_connect_confirm(void *instance, void *sap,
279                                               struct qos_info *qos,
280                                               __u32 max_sdu_size,
281                                               __u8 max_header_size,
282                                               struct sk_buff *skb)
283 {
284         struct irlan_cb *self;
285
286         self = instance;
287
288         IRDA_ASSERT(self != NULL, return;);
289         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
290
291         self->client.max_sdu_size = max_sdu_size;
292         self->client.max_header_size = max_header_size;
293
294         /* TODO: we could set the MTU depending on the max_sdu_size */
295
296         irlan_do_client_event(self, IRLAN_CONNECT_COMPLETE, NULL);
297 }
298
299 /*
300  * Function print_ret_code (code)
301  *
302  *    Print return code of request to peer IrLAN layer.
303  *
304  */
305 static void print_ret_code(__u8 code)
306 {
307         switch(code) {
308         case 0:
309                 printk(KERN_INFO "Success\n");
310                 break;
311         case 1:
312                 net_warn_ratelimited("IrLAN: Insufficient resources\n");
313                 break;
314         case 2:
315                 net_warn_ratelimited("IrLAN: Invalid command format\n");
316                 break;
317         case 3:
318                 net_warn_ratelimited("IrLAN: Command not supported\n");
319                 break;
320         case 4:
321                 net_warn_ratelimited("IrLAN: Parameter not supported\n");
322                 break;
323         case 5:
324                 net_warn_ratelimited("IrLAN: Value not supported\n");
325                 break;
326         case 6:
327                 net_warn_ratelimited("IrLAN: Not open\n");
328                 break;
329         case 7:
330                 net_warn_ratelimited("IrLAN: Authentication required\n");
331                 break;
332         case 8:
333                 net_warn_ratelimited("IrLAN: Invalid password\n");
334                 break;
335         case 9:
336                 net_warn_ratelimited("IrLAN: Protocol error\n");
337                 break;
338         case 255:
339                 net_warn_ratelimited("IrLAN: Asynchronous status\n");
340                 break;
341         }
342 }
343
344 /*
345  * Function irlan_client_parse_response (self, skb)
346  *
347  *    Extract all parameters from received buffer, then feed them to
348  *    check_params for parsing
349  */
350 void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb)
351 {
352         __u8 *frame;
353         __u8 *ptr;
354         int count;
355         int ret;
356         __u16 val_len;
357         int i;
358         char *name;
359         char *value;
360
361         IRDA_ASSERT(skb != NULL, return;);
362
363         pr_debug("%s() skb->len=%d\n", __func__ , (int)skb->len);
364
365         IRDA_ASSERT(self != NULL, return;);
366         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
367
368         if (!skb) {
369                 net_err_ratelimited("%s(), Got NULL skb!\n", __func__);
370                 return;
371         }
372         frame = skb->data;
373
374         /*
375          *  Check return code and print it if not success
376          */
377         if (frame[0]) {
378                 print_ret_code(frame[0]);
379                 return;
380         }
381
382         name = kmalloc(255, GFP_ATOMIC);
383         if (!name)
384                 return;
385         value = kmalloc(1016, GFP_ATOMIC);
386         if (!value) {
387                 kfree(name);
388                 return;
389         }
390
391         /* How many parameters? */
392         count = frame[1];
393
394         pr_debug("%s(), got %d parameters\n", __func__ , count);
395
396         ptr = frame+2;
397
398         /* For all parameters */
399         for (i=0; i<count;i++) {
400                 ret = irlan_extract_param(ptr, name, value, &val_len);
401                 if (ret < 0) {
402                         pr_debug("%s(), IrLAN, Error!\n", __func__);
403                         break;
404                 }
405                 ptr += ret;
406                 irlan_check_response_param(self, name, value, val_len);
407         }
408         /* Cleanup */
409         kfree(name);
410         kfree(value);
411 }
412
413 /*
414  * Function irlan_check_response_param (self, param, value, val_len)
415  *
416  *     Check which parameter is received and update local variables
417  *
418  */
419 static void irlan_check_response_param(struct irlan_cb *self, char *param,
420                                        char *value, int val_len)
421 {
422         __u16 tmp_cpu; /* Temporary value in host order */
423         __u8 *bytes;
424         int i;
425
426         pr_debug("%s(), parm=%s\n", __func__ , param);
427
428         IRDA_ASSERT(self != NULL, return;);
429         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
430
431         /* Media type */
432         if (strcmp(param, "MEDIA") == 0) {
433                 if (strcmp(value, "802.3") == 0)
434                         self->media = MEDIA_802_3;
435                 else
436                         self->media = MEDIA_802_5;
437                 return;
438         }
439         if (strcmp(param, "FILTER_TYPE") == 0) {
440                 if (strcmp(value, "DIRECTED") == 0)
441                         self->client.filter_type |= IRLAN_DIRECTED;
442                 else if (strcmp(value, "FUNCTIONAL") == 0)
443                         self->client.filter_type |= IRLAN_FUNCTIONAL;
444                 else if (strcmp(value, "GROUP") == 0)
445                         self->client.filter_type |= IRLAN_GROUP;
446                 else if (strcmp(value, "MAC_FRAME") == 0)
447                         self->client.filter_type |= IRLAN_MAC_FRAME;
448                 else if (strcmp(value, "MULTICAST") == 0)
449                         self->client.filter_type |= IRLAN_MULTICAST;
450                 else if (strcmp(value, "BROADCAST") == 0)
451                         self->client.filter_type |= IRLAN_BROADCAST;
452                 else if (strcmp(value, "IPX_SOCKET") == 0)
453                         self->client.filter_type |= IRLAN_IPX_SOCKET;
454
455         }
456         if (strcmp(param, "ACCESS_TYPE") == 0) {
457                 if (strcmp(value, "DIRECT") == 0)
458                         self->client.access_type = ACCESS_DIRECT;
459                 else if (strcmp(value, "PEER") == 0)
460                         self->client.access_type = ACCESS_PEER;
461                 else if (strcmp(value, "HOSTED") == 0)
462                         self->client.access_type = ACCESS_HOSTED;
463                 else {
464                         pr_debug("%s(), unknown access type!\n", __func__);
465                 }
466         }
467         /* IRLAN version */
468         if (strcmp(param, "IRLAN_VER") == 0) {
469                 pr_debug("IrLAN version %d.%d\n", (__u8)value[0],
470                          (__u8)value[1]);
471
472                 self->version[0] = value[0];
473                 self->version[1] = value[1];
474                 return;
475         }
476         /* Which remote TSAP to use for data channel */
477         if (strcmp(param, "DATA_CHAN") == 0) {
478                 self->dtsap_sel_data = value[0];
479                 pr_debug("Data TSAP = %02x\n", self->dtsap_sel_data);
480                 return;
481         }
482         if (strcmp(param, "CON_ARB") == 0) {
483                 memcpy(&tmp_cpu, value, 2); /* Align value */
484                 le16_to_cpus(&tmp_cpu);     /* Convert to host order */
485                 self->client.recv_arb_val = tmp_cpu;
486                 pr_debug("%s(), receive arb val=%d\n", __func__ ,
487                          self->client.recv_arb_val);
488         }
489         if (strcmp(param, "MAX_FRAME") == 0) {
490                 memcpy(&tmp_cpu, value, 2); /* Align value */
491                 le16_to_cpus(&tmp_cpu);     /* Convert to host order */
492                 self->client.max_frame = tmp_cpu;
493                 pr_debug("%s(), max frame=%d\n", __func__ ,
494                          self->client.max_frame);
495         }
496
497         /* RECONNECT_KEY, in case the link goes down! */
498         if (strcmp(param, "RECONNECT_KEY") == 0) {
499                 pr_debug("Got reconnect key: ");
500                 /* for (i = 0; i < val_len; i++) */
501 /*                      printk("%02x", value[i]); */
502                 memcpy(self->client.reconnect_key, value, val_len);
503                 self->client.key_len = val_len;
504                 pr_debug("\n");
505         }
506         /* FILTER_ENTRY, have we got an ethernet address? */
507         if (strcmp(param, "FILTER_ENTRY") == 0) {
508                 bytes = value;
509                 pr_debug("Ethernet address = %pM\n", bytes);
510                 for (i = 0; i < 6; i++)
511                         self->dev->dev_addr[i] = bytes[i];
512         }
513 }
514
515 /*
516  * Function irlan_client_get_value_confirm (obj_id, value)
517  *
518  *    Got results from remote LM-IAS
519  *
520  */
521 void irlan_client_get_value_confirm(int result, __u16 obj_id,
522                                     struct ias_value *value, void *priv)
523 {
524         struct irlan_cb *self;
525
526         IRDA_ASSERT(priv != NULL, return;);
527
528         self = priv;
529         IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
530
531         /* We probably don't need to make any more queries */
532         iriap_close(self->client.iriap);
533         self->client.iriap = NULL;
534
535         /* Check if request succeeded */
536         if (result != IAS_SUCCESS) {
537                 pr_debug("%s(), got NULL value!\n", __func__);
538                 irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL,
539                                       NULL);
540                 return;
541         }
542
543         switch (value->type) {
544         case IAS_INTEGER:
545                 self->dtsap_sel_ctrl = value->t.integer;
546
547                 if (value->t.integer != -1) {
548                         irlan_do_client_event(self, IRLAN_IAS_PROVIDER_AVAIL,
549                                               NULL);
550                         return;
551                 }
552                 irias_delete_value(value);
553                 break;
554         default:
555                 pr_debug("%s(), unknown type!\n", __func__);
556                 break;
557         }
558         irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, NULL);
559 }