28d9fd727d843cc4950c3292e6fa92f72662d694
[pandora-kernel.git] / drivers / char / pcmcia / ipwireless / network.c
1 /*
2  * IPWireless 3G PCMCIA Network Driver
3  *
4  * Original code
5  *   by Stephen Blackheath <stephen@blacksapphire.com>,
6  *      Ben Martel <benm@symmetric.co.nz>
7  *
8  * Copyrighted as follows:
9  *   Copyright (C) 2004 by Symmetric Systems Ltd (NZ)
10  *
11  * Various driver changes and rewrites, port to new kernels
12  *   Copyright (C) 2006-2007 Jiri Kosina
13  *
14  * Misc code cleanups and updates
15  *   Copyright (C) 2007 David Sterba
16  */
17
18 #include <linux/interrupt.h>
19 #include <linux/kernel.h>
20 #include <linux/mutex.h>
21 #include <linux/netdevice.h>
22 #include <linux/ppp_channel.h>
23 #include <linux/ppp_defs.h>
24 #include <linux/if_ppp.h>
25 #include <linux/skbuff.h>
26
27 #include "network.h"
28 #include "hardware.h"
29 #include "main.h"
30 #include "tty.h"
31
32 #define MAX_ASSOCIATED_TTYS 2
33
34 #define SC_RCV_BITS     (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
35
36 struct ipw_network {
37         /* Hardware context, used for calls to hardware layer. */
38         struct ipw_hardware *hardware;
39         /* Context for kernel 'generic_ppp' functionality */
40         struct ppp_channel *ppp_channel;
41         /* tty context connected with IPW console */
42         struct ipw_tty *associated_ttys[NO_OF_IPW_CHANNELS][MAX_ASSOCIATED_TTYS];
43         /* True if ppp needs waking up once we're ready to xmit */
44         int ppp_blocked;
45         /* Number of packets queued up in hardware module. */
46         int outgoing_packets_queued;
47         /* Spinlock to avoid interrupts during shutdown */
48         spinlock_t lock;
49         struct mutex close_lock;
50
51         /* PPP ioctl data, not actually used anywere */
52         unsigned int flags;
53         unsigned int rbits;
54         u32 xaccm[8];
55         u32 raccm;
56         int mru;
57
58         int shutting_down;
59         unsigned int ras_control_lines;
60
61         struct work_struct work_go_online;
62         struct work_struct work_go_offline;
63 };
64
65 static void notify_packet_sent(void *callback_data, unsigned int packet_length)
66 {
67         struct ipw_network *network = callback_data;
68         unsigned long flags;
69
70         spin_lock_irqsave(&network->lock, flags);
71         network->outgoing_packets_queued--;
72         if (network->ppp_channel != NULL) {
73                 if (network->ppp_blocked) {
74                         network->ppp_blocked = 0;
75                         spin_unlock_irqrestore(&network->lock, flags);
76                         ppp_output_wakeup(network->ppp_channel);
77                         if (ipwireless_debug)
78                                 printk(KERN_INFO IPWIRELESS_PCCARD_NAME
79                                        ": ppp unblocked\n");
80                 } else
81                         spin_unlock_irqrestore(&network->lock, flags);
82         } else
83                 spin_unlock_irqrestore(&network->lock, flags);
84 }
85
86 /*
87  * Called by the ppp system when it has a packet to send to the hardware.
88  */
89 static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel,
90                                      struct sk_buff *skb)
91 {
92         struct ipw_network *network = ppp_channel->private;
93         unsigned long flags;
94
95         spin_lock_irqsave(&network->lock, flags);
96         if (network->outgoing_packets_queued < ipwireless_out_queue) {
97                 unsigned char *buf;
98                 static unsigned char header[] = {
99                         PPP_ALLSTATIONS, /* 0xff */
100                         PPP_UI,          /* 0x03 */
101                 };
102                 int ret;
103
104                 network->outgoing_packets_queued++;
105                 spin_unlock_irqrestore(&network->lock, flags);
106
107                 /*
108                  * If we have the requested amount of headroom in the skb we
109                  * were handed, then we can add the header efficiently.
110                  */
111                 if (skb_headroom(skb) >= 2) {
112                         memcpy(skb_push(skb, 2), header, 2);
113                         ret = ipwireless_send_packet(network->hardware,
114                                                IPW_CHANNEL_RAS, skb->data,
115                                                skb->len,
116                                                notify_packet_sent,
117                                                network);
118                         if (ret == -1) {
119                                 skb_pull(skb, 2);
120                                 return 0;
121                         }
122                 } else {
123                         /* Otherwise (rarely) we do it inefficiently. */
124                         buf = kmalloc(skb->len + 2, GFP_ATOMIC);
125                         if (!buf)
126                                 return 0;
127                         memcpy(buf + 2, skb->data, skb->len);
128                         memcpy(buf, header, 2);
129                         ret = ipwireless_send_packet(network->hardware,
130                                                IPW_CHANNEL_RAS, buf,
131                                                skb->len + 2,
132                                                notify_packet_sent,
133                                                network);
134                         kfree(buf);
135                         if (ret == -1)
136                                 return 0;
137                 }
138                 kfree_skb(skb);
139                 return 1;
140         } else {
141                 /*
142                  * Otherwise reject the packet, and flag that the ppp system
143                  * needs to be unblocked once we are ready to send.
144                  */
145                 network->ppp_blocked = 1;
146                 spin_unlock_irqrestore(&network->lock, flags);
147                 return 0;
148         }
149 }
150
151 /* Handle an ioctl call that has come in via ppp. (copy of ppp_async_ioctl() */
152 static int ipwireless_ppp_ioctl(struct ppp_channel *ppp_channel,
153                                 unsigned int cmd, unsigned long arg)
154 {
155         struct ipw_network *network = ppp_channel->private;
156         int err, val;
157         u32 accm[8];
158         int __user *user_arg = (int __user *) arg;
159
160         err = -EFAULT;
161         switch (cmd) {
162         case PPPIOCGFLAGS:
163                 val = network->flags | network->rbits;
164                 if (put_user(val, user_arg))
165                         break;
166                 err = 0;
167                 break;
168
169         case PPPIOCSFLAGS:
170                 if (get_user(val, user_arg))
171                         break;
172                 network->flags = val & ~SC_RCV_BITS;
173                 network->rbits = val & SC_RCV_BITS;
174                 err = 0;
175                 break;
176
177         case PPPIOCGASYNCMAP:
178                 if (put_user(network->xaccm[0], user_arg))
179                         break;
180                 err = 0;
181                 break;
182
183         case PPPIOCSASYNCMAP:
184                 if (get_user(network->xaccm[0], user_arg))
185                         break;
186                 err = 0;
187                 break;
188
189         case PPPIOCGRASYNCMAP:
190                 if (put_user(network->raccm, user_arg))
191                         break;
192                 err = 0;
193                 break;
194
195         case PPPIOCSRASYNCMAP:
196                 if (get_user(network->raccm, user_arg))
197                         break;
198                 err = 0;
199                 break;
200
201         case PPPIOCGXASYNCMAP:
202                 if (copy_to_user((void __user *) arg, network->xaccm,
203                                         sizeof(network->xaccm)))
204                         break;
205                 err = 0;
206                 break;
207
208         case PPPIOCSXASYNCMAP:
209                 if (copy_from_user(accm, (void __user *) arg, sizeof(accm)))
210                         break;
211                 accm[2] &= ~0x40000000U;        /* can't escape 0x5e */
212                 accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */
213                 memcpy(network->xaccm, accm, sizeof(network->xaccm));
214                 err = 0;
215                 break;
216
217         case PPPIOCGMRU:
218                 if (put_user(network->mru, user_arg))
219                         break;
220                 err = 0;
221                 break;
222
223         case PPPIOCSMRU:
224                 if (get_user(val, user_arg))
225                         break;
226                 if (val < PPP_MRU)
227                         val = PPP_MRU;
228                 network->mru = val;
229                 err = 0;
230                 break;
231
232         default:
233                 err = -ENOTTY;
234         }
235
236         return err;
237 }
238
239 static struct ppp_channel_ops ipwireless_ppp_channel_ops = {
240         .start_xmit = ipwireless_ppp_start_xmit,
241         .ioctl      = ipwireless_ppp_ioctl
242 };
243
244 static void do_go_online(struct work_struct *work_go_online)
245 {
246         struct ipw_network *network =
247                 container_of(work_go_online, struct ipw_network,
248                                 work_go_online);
249         unsigned long flags;
250
251         spin_lock_irqsave(&network->lock, flags);
252         if (!network->ppp_channel) {
253                 struct ppp_channel *channel;
254
255                 spin_unlock_irqrestore(&network->lock, flags);
256                 channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL);
257                 if (!channel) {
258                         printk(KERN_ERR IPWIRELESS_PCCARD_NAME
259                                         ": unable to allocate PPP channel\n");
260                         return;
261                 }
262                 channel->private = network;
263                 channel->mtu = 16384;   /* Wild guess */
264                 channel->hdrlen = 2;
265                 channel->ops = &ipwireless_ppp_channel_ops;
266
267                 network->flags = 0;
268                 network->rbits = 0;
269                 network->mru = PPP_MRU;
270                 memset(network->xaccm, 0, sizeof(network->xaccm));
271                 network->xaccm[0] = ~0U;
272                 network->xaccm[3] = 0x60000000U;
273                 network->raccm = ~0U;
274                 ppp_register_channel(channel);
275                 spin_lock_irqsave(&network->lock, flags);
276                 network->ppp_channel = channel;
277         }
278         spin_unlock_irqrestore(&network->lock, flags);
279 }
280
281 static void do_go_offline(struct work_struct *work_go_offline)
282 {
283         struct ipw_network *network =
284                 container_of(work_go_offline, struct ipw_network,
285                                 work_go_offline);
286         unsigned long flags;
287
288         mutex_lock(&network->close_lock);
289         spin_lock_irqsave(&network->lock, flags);
290         if (network->ppp_channel != NULL) {
291                 struct ppp_channel *channel = network->ppp_channel;
292
293                 network->ppp_channel = NULL;
294                 spin_unlock_irqrestore(&network->lock, flags);
295                 mutex_unlock(&network->close_lock);
296                 ppp_unregister_channel(channel);
297         } else {
298                 spin_unlock_irqrestore(&network->lock, flags);
299                 mutex_unlock(&network->close_lock);
300         }
301 }
302
303 void ipwireless_network_notify_control_line_change(struct ipw_network *network,
304                                                    unsigned int channel_idx,
305                                                    unsigned int control_lines,
306                                                    unsigned int changed_mask)
307 {
308         int i;
309
310         if (channel_idx == IPW_CHANNEL_RAS)
311                 network->ras_control_lines = control_lines;
312
313         for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) {
314                 struct ipw_tty *tty =
315                         network->associated_ttys[channel_idx][i];
316
317                 /*
318                  * If it's associated with a tty (other than the RAS channel
319                  * when we're online), then send the data to that tty.  The RAS
320                  * channel's data is handled above - it always goes through
321                  * ppp_generic.
322                  */
323                 if (tty)
324                         ipwireless_tty_notify_control_line_change(tty,
325                                                                   channel_idx,
326                                                                   control_lines,
327                                                                   changed_mask);
328         }
329 }
330
331 /*
332  * Some versions of firmware stuff packets with 0xff 0x03 (PPP: ALLSTATIONS, UI)
333  * bytes, which are required on sent packet, but not always present on received
334  * packets
335  */
336 static struct sk_buff *ipw_packet_received_skb(unsigned char *data,
337                                                unsigned int length)
338 {
339         struct sk_buff *skb;
340
341         if (length > 2 && data[0] == PPP_ALLSTATIONS && data[1] == PPP_UI) {
342                 length -= 2;
343                 data += 2;
344         }
345
346         skb = dev_alloc_skb(length + 4);
347         skb_reserve(skb, 2);
348         memcpy(skb_put(skb, length), data, length);
349
350         return skb;
351 }
352
353 void ipwireless_network_packet_received(struct ipw_network *network,
354                                         unsigned int channel_idx,
355                                         unsigned char *data,
356                                         unsigned int length)
357 {
358         int i;
359         unsigned long flags;
360
361         for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) {
362                 struct ipw_tty *tty = network->associated_ttys[channel_idx][i];
363
364                 if (!tty)
365                         continue;
366
367                 /*
368                  * If it's associated with a tty (other than the RAS channel
369                  * when we're online), then send the data to that tty.  The RAS
370                  * channel's data is handled above - it always goes through
371                  * ppp_generic.
372                  */
373                 if (channel_idx == IPW_CHANNEL_RAS
374                                 && (network->ras_control_lines &
375                                         IPW_CONTROL_LINE_DCD) != 0
376                                 && ipwireless_tty_is_modem(tty)) {
377                         /*
378                          * If data came in on the RAS channel and this tty is
379                          * the modem tty, and we are online, then we send it to
380                          * the PPP layer.
381                          */
382                         mutex_lock(&network->close_lock);
383                         spin_lock_irqsave(&network->lock, flags);
384                         if (network->ppp_channel != NULL) {
385                                 struct sk_buff *skb;
386
387                                 spin_unlock_irqrestore(&network->lock,
388                                                 flags);
389
390                                 /* Send the data to the ppp_generic module. */
391                                 skb = ipw_packet_received_skb(data, length);
392                                 ppp_input(network->ppp_channel, skb);
393                         } else
394                                 spin_unlock_irqrestore(&network->lock,
395                                                 flags);
396                         mutex_unlock(&network->close_lock);
397                 }
398                 /* Otherwise we send it out the tty. */
399                 else
400                         ipwireless_tty_received(tty, data, length);
401         }
402 }
403
404 struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw)
405 {
406         struct ipw_network *network =
407                 kzalloc(sizeof(struct ipw_network), GFP_ATOMIC);
408
409         if (!network)
410                 return NULL;
411
412         spin_lock_init(&network->lock);
413         mutex_init(&network->close_lock);
414
415         network->hardware = hw;
416
417         INIT_WORK(&network->work_go_online, do_go_online);
418         INIT_WORK(&network->work_go_offline, do_go_offline);
419
420         ipwireless_associate_network(hw, network);
421
422         return network;
423 }
424
425 void ipwireless_network_free(struct ipw_network *network)
426 {
427         network->shutting_down = 1;
428
429         ipwireless_ppp_close(network);
430         flush_scheduled_work();
431
432         ipwireless_stop_interrupts(network->hardware);
433         ipwireless_associate_network(network->hardware, NULL);
434
435         kfree(network);
436 }
437
438 void ipwireless_associate_network_tty(struct ipw_network *network,
439                                       unsigned int channel_idx,
440                                       struct ipw_tty *tty)
441 {
442         int i;
443
444         for (i = 0; i < MAX_ASSOCIATED_TTYS; i++)
445                 if (network->associated_ttys[channel_idx][i] == NULL) {
446                         network->associated_ttys[channel_idx][i] = tty;
447                         break;
448                 }
449 }
450
451 void ipwireless_disassociate_network_ttys(struct ipw_network *network,
452                                           unsigned int channel_idx)
453 {
454         int i;
455
456         for (i = 0; i < MAX_ASSOCIATED_TTYS; i++)
457                 network->associated_ttys[channel_idx][i] = NULL;
458 }
459
460 void ipwireless_ppp_open(struct ipw_network *network)
461 {
462         if (ipwireless_debug)
463                 printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": online\n");
464         schedule_work(&network->work_go_online);
465 }
466
467 void ipwireless_ppp_close(struct ipw_network *network)
468 {
469         /* Disconnect from the wireless network. */
470         if (ipwireless_debug)
471                 printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": offline\n");
472         schedule_work(&network->work_go_offline);
473 }
474
475 int ipwireless_ppp_channel_index(struct ipw_network *network)
476 {
477         int ret = -1;
478         unsigned long flags;
479
480         spin_lock_irqsave(&network->lock, flags);
481         if (network->ppp_channel != NULL)
482                 ret = ppp_channel_index(network->ppp_channel);
483         spin_unlock_irqrestore(&network->lock, flags);
484
485         return ret;
486 }
487
488 int ipwireless_ppp_unit_number(struct ipw_network *network)
489 {
490         int ret = -1;
491         unsigned long flags;
492
493         spin_lock_irqsave(&network->lock, flags);
494         if (network->ppp_channel != NULL)
495                 ret = ppp_unit_number(network->ppp_channel);
496         spin_unlock_irqrestore(&network->lock, flags);
497
498         return ret;
499 }