Merge branch 'writeback' of git://git.kernel.dk/linux-2.6-block
[pandora-kernel.git] / drivers / usb / gadget / f_eem.c
1 /*
2  * f_eem.c -- USB CDC Ethernet (EEM) link function driver
3  *
4  * Copyright (C) 2003-2005,2008 David Brownell
5  * Copyright (C) 2008 Nokia Corporation
6  * Copyright (C) 2009 EF Johnson Technologies
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <linux/kernel.h>
24 #include <linux/device.h>
25 #include <linux/etherdevice.h>
26 #include <linux/crc32.h>
27
28 #include "u_ether.h"
29
30 #define EEM_HLEN 2
31
32 /*
33  * This function is a "CDC Ethernet Emulation Model" (CDC EEM)
34  * Ethernet link.
35  */
36
37 struct eem_ep_descs {
38         struct usb_endpoint_descriptor  *in;
39         struct usb_endpoint_descriptor  *out;
40 };
41
42 struct f_eem {
43         struct gether                   port;
44         u8                              ctrl_id;
45
46         struct eem_ep_descs             fs;
47         struct eem_ep_descs             hs;
48 };
49
50 static inline struct f_eem *func_to_eem(struct usb_function *f)
51 {
52         return container_of(f, struct f_eem, port.func);
53 }
54
55 /*-------------------------------------------------------------------------*/
56
57 /* interface descriptor: */
58
59 static struct usb_interface_descriptor eem_intf __initdata = {
60         .bLength =              sizeof eem_intf,
61         .bDescriptorType =      USB_DT_INTERFACE,
62
63         /* .bInterfaceNumber = DYNAMIC */
64         .bNumEndpoints =        2,
65         .bInterfaceClass =      USB_CLASS_COMM,
66         .bInterfaceSubClass =   USB_CDC_SUBCLASS_EEM,
67         .bInterfaceProtocol =   USB_CDC_PROTO_EEM,
68         /* .iInterface = DYNAMIC */
69 };
70
71 /* full speed support: */
72
73 static struct usb_endpoint_descriptor eem_fs_in_desc __initdata = {
74         .bLength =              USB_DT_ENDPOINT_SIZE,
75         .bDescriptorType =      USB_DT_ENDPOINT,
76
77         .bEndpointAddress =     USB_DIR_IN,
78         .bmAttributes =         USB_ENDPOINT_XFER_BULK,
79 };
80
81 static struct usb_endpoint_descriptor eem_fs_out_desc __initdata = {
82         .bLength =              USB_DT_ENDPOINT_SIZE,
83         .bDescriptorType =      USB_DT_ENDPOINT,
84
85         .bEndpointAddress =     USB_DIR_OUT,
86         .bmAttributes =         USB_ENDPOINT_XFER_BULK,
87 };
88
89 static struct usb_descriptor_header *eem_fs_function[] __initdata = {
90         /* CDC EEM control descriptors */
91         (struct usb_descriptor_header *) &eem_intf,
92         (struct usb_descriptor_header *) &eem_fs_in_desc,
93         (struct usb_descriptor_header *) &eem_fs_out_desc,
94         NULL,
95 };
96
97 /* high speed support: */
98
99 static struct usb_endpoint_descriptor eem_hs_in_desc __initdata = {
100         .bLength =              USB_DT_ENDPOINT_SIZE,
101         .bDescriptorType =      USB_DT_ENDPOINT,
102
103         .bEndpointAddress =     USB_DIR_IN,
104         .bmAttributes =         USB_ENDPOINT_XFER_BULK,
105         .wMaxPacketSize =       cpu_to_le16(512),
106 };
107
108 static struct usb_endpoint_descriptor eem_hs_out_desc __initdata = {
109         .bLength =              USB_DT_ENDPOINT_SIZE,
110         .bDescriptorType =      USB_DT_ENDPOINT,
111
112         .bEndpointAddress =     USB_DIR_OUT,
113         .bmAttributes =         USB_ENDPOINT_XFER_BULK,
114         .wMaxPacketSize =       cpu_to_le16(512),
115 };
116
117 static struct usb_descriptor_header *eem_hs_function[] __initdata = {
118         /* CDC EEM control descriptors */
119         (struct usb_descriptor_header *) &eem_intf,
120         (struct usb_descriptor_header *) &eem_hs_in_desc,
121         (struct usb_descriptor_header *) &eem_hs_out_desc,
122         NULL,
123 };
124
125 /* string descriptors: */
126
127 static struct usb_string eem_string_defs[] = {
128         [0].s = "CDC Ethernet Emulation Model (EEM)",
129         {  } /* end of list */
130 };
131
132 static struct usb_gadget_strings eem_string_table = {
133         .language =             0x0409, /* en-us */
134         .strings =              eem_string_defs,
135 };
136
137 static struct usb_gadget_strings *eem_strings[] = {
138         &eem_string_table,
139         NULL,
140 };
141
142 /*-------------------------------------------------------------------------*/
143
144 static int eem_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
145 {
146         struct usb_composite_dev *cdev = f->config->cdev;
147         int                     value = -EOPNOTSUPP;
148         u16                     w_index = le16_to_cpu(ctrl->wIndex);
149         u16                     w_value = le16_to_cpu(ctrl->wValue);
150         u16                     w_length = le16_to_cpu(ctrl->wLength);
151
152         DBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
153                 ctrl->bRequestType, ctrl->bRequest,
154                 w_value, w_index, w_length);
155
156         /* device either stalls (value < 0) or reports success */
157         return value;
158 }
159
160
161 static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
162 {
163         struct f_eem            *eem = func_to_eem(f);
164         struct usb_composite_dev *cdev = f->config->cdev;
165         struct net_device       *net;
166
167         /* we know alt == 0, so this is an activation or a reset */
168         if (alt != 0)
169                 goto fail;
170
171         if (intf == eem->ctrl_id) {
172
173                 if (eem->port.in_ep->driver_data) {
174                         DBG(cdev, "reset eem\n");
175                         gether_disconnect(&eem->port);
176                 }
177
178                 if (!eem->port.in) {
179                         DBG(cdev, "init eem\n");
180                         eem->port.in = ep_choose(cdev->gadget,
181                                         eem->hs.in, eem->fs.in);
182                         eem->port.out = ep_choose(cdev->gadget,
183                                         eem->hs.out, eem->fs.out);
184                 }
185
186                 /* zlps should not occur because zero-length EEM packets
187                  * will be inserted in those cases where they would occur
188                  */
189                 eem->port.is_zlp_ok = 1;
190                 eem->port.cdc_filter = DEFAULT_FILTER;
191                 DBG(cdev, "activate eem\n");
192                 net = gether_connect(&eem->port);
193                 if (IS_ERR(net))
194                         return PTR_ERR(net);
195         } else
196                 goto fail;
197
198         return 0;
199 fail:
200         return -EINVAL;
201 }
202
203 static void eem_disable(struct usb_function *f)
204 {
205         struct f_eem            *eem = func_to_eem(f);
206         struct usb_composite_dev *cdev = f->config->cdev;
207
208         DBG(cdev, "eem deactivated\n");
209
210         if (eem->port.in_ep->driver_data)
211                 gether_disconnect(&eem->port);
212 }
213
214 /*-------------------------------------------------------------------------*/
215
216 /* EEM function driver setup/binding */
217
218 static int __init
219 eem_bind(struct usb_configuration *c, struct usb_function *f)
220 {
221         struct usb_composite_dev *cdev = c->cdev;
222         struct f_eem            *eem = func_to_eem(f);
223         int                     status;
224         struct usb_ep           *ep;
225
226         /* allocate instance-specific interface IDs */
227         status = usb_interface_id(c, f);
228         if (status < 0)
229                 goto fail;
230         eem->ctrl_id = status;
231         eem_intf.bInterfaceNumber = status;
232
233         status = -ENODEV;
234
235         /* allocate instance-specific endpoints */
236         ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_in_desc);
237         if (!ep)
238                 goto fail;
239         eem->port.in_ep = ep;
240         ep->driver_data = cdev; /* claim */
241
242         ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc);
243         if (!ep)
244                 goto fail;
245         eem->port.out_ep = ep;
246         ep->driver_data = cdev; /* claim */
247
248         status = -ENOMEM;
249
250         /* copy descriptors, and track endpoint copies */
251         f->descriptors = usb_copy_descriptors(eem_fs_function);
252         if (!f->descriptors)
253                 goto fail;
254
255         eem->fs.in = usb_find_endpoint(eem_fs_function,
256                         f->descriptors, &eem_fs_in_desc);
257         eem->fs.out = usb_find_endpoint(eem_fs_function,
258                         f->descriptors, &eem_fs_out_desc);
259
260         /* support all relevant hardware speeds... we expect that when
261          * hardware is dual speed, all bulk-capable endpoints work at
262          * both speeds
263          */
264         if (gadget_is_dualspeed(c->cdev->gadget)) {
265                 eem_hs_in_desc.bEndpointAddress =
266                                 eem_fs_in_desc.bEndpointAddress;
267                 eem_hs_out_desc.bEndpointAddress =
268                                 eem_fs_out_desc.bEndpointAddress;
269
270                 /* copy descriptors, and track endpoint copies */
271                 f->hs_descriptors = usb_copy_descriptors(eem_hs_function);
272                 if (!f->hs_descriptors)
273                         goto fail;
274
275                 eem->hs.in = usb_find_endpoint(eem_hs_function,
276                                 f->hs_descriptors, &eem_hs_in_desc);
277                 eem->hs.out = usb_find_endpoint(eem_hs_function,
278                                 f->hs_descriptors, &eem_hs_out_desc);
279         }
280
281         DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
282                         gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
283                         eem->port.in_ep->name, eem->port.out_ep->name);
284         return 0;
285
286 fail:
287         if (f->descriptors)
288                 usb_free_descriptors(f->descriptors);
289
290         /* we might as well release our claims on endpoints */
291         if (eem->port.out)
292                 eem->port.out_ep->driver_data = NULL;
293         if (eem->port.in)
294                 eem->port.in_ep->driver_data = NULL;
295
296         ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
297
298         return status;
299 }
300
301 static void
302 eem_unbind(struct usb_configuration *c, struct usb_function *f)
303 {
304         struct f_eem    *eem = func_to_eem(f);
305
306         DBG(c->cdev, "eem unbind\n");
307
308         if (gadget_is_dualspeed(c->cdev->gadget))
309                 usb_free_descriptors(f->hs_descriptors);
310         usb_free_descriptors(f->descriptors);
311         kfree(eem);
312 }
313
314 static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req)
315 {
316 }
317
318 /*
319  * Add the EEM header and ethernet checksum.
320  * We currently do not attempt to put multiple ethernet frames
321  * into a single USB transfer
322  */
323 static struct sk_buff *eem_wrap(struct gether *port, struct sk_buff *skb)
324 {
325         struct sk_buff  *skb2 = NULL;
326         struct usb_ep   *in = port->in_ep;
327         int             padlen = 0;
328         u16             len = skb->len;
329
330         if (!skb_cloned(skb)) {
331                 int headroom = skb_headroom(skb);
332                 int tailroom = skb_tailroom(skb);
333
334                 /* When (len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) is 0,
335                  * stick two bytes of zero-length EEM packet on the end.
336                  */
337                 if (((len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) == 0)
338                         padlen += 2;
339
340                 if ((tailroom >= (ETH_FCS_LEN + padlen)) &&
341                                 (headroom >= EEM_HLEN))
342                         goto done;
343         }
344
345         skb2 = skb_copy_expand(skb, EEM_HLEN, ETH_FCS_LEN + padlen, GFP_ATOMIC);
346         dev_kfree_skb_any(skb);
347         skb = skb2;
348         if (!skb)
349                 return skb;
350
351 done:
352         /* use the "no CRC" option */
353         put_unaligned_be32(0xdeadbeef, skb_put(skb, 4));
354
355         /* EEM packet header format:
356          * b0..13:      length of ethernet frame
357          * b14:         bmCRC (0 == sentinel CRC)
358          * b15:         bmType (0 == data)
359          */
360         len = skb->len;
361         put_unaligned_le16((len & 0x3FFF) | BIT(14), skb_push(skb, 2));
362
363         /* add a zero-length EEM packet, if needed */
364         if (padlen)
365                 put_unaligned_le16(0, skb_put(skb, 2));
366
367         return skb;
368 }
369
370 /*
371  * Remove the EEM header.  Note that there can be many EEM packets in a single
372  * USB transfer, so we need to break them out and handle them independently.
373  */
374 static int eem_unwrap(struct gether *port,
375                         struct sk_buff *skb,
376                         struct sk_buff_head *list)
377 {
378         struct usb_composite_dev        *cdev = port->func.config->cdev;
379         int                             status = 0;
380
381         do {
382                 struct sk_buff  *skb2;
383                 u16             header;
384                 u16             len = 0;
385
386                 if (skb->len < EEM_HLEN) {
387                         status = -EINVAL;
388                         DBG(cdev, "invalid EEM header\n");
389                         goto error;
390                 }
391
392                 /* remove the EEM header */
393                 header = get_unaligned_le16(skb->data);
394                 skb_pull(skb, EEM_HLEN);
395
396                 /* EEM packet header format:
397                  * b0..14:      EEM type dependent (data or command)
398                  * b15:         bmType (0 == data, 1 == command)
399                  */
400                 if (header & BIT(15)) {
401                         struct usb_request      *req = cdev->req;
402                         u16                     bmEEMCmd;
403
404                         /* EEM command packet format:
405                          * b0..10:      bmEEMCmdParam
406                          * b11..13:     bmEEMCmd
407                          * b14:         reserved (must be zero)
408                          * b15:         bmType (1 == command)
409                          */
410                         if (header & BIT(14))
411                                 continue;
412
413                         bmEEMCmd = (header >> 11) & 0x7;
414                         switch (bmEEMCmd) {
415                         case 0: /* echo */
416                                 len = header & 0x7FF;
417                                 if (skb->len < len) {
418                                         status = -EOVERFLOW;
419                                         goto error;
420                                 }
421
422                                 skb2 = skb_clone(skb, GFP_ATOMIC);
423                                 if (unlikely(!skb2)) {
424                                         DBG(cdev, "EEM echo response error\n");
425                                         goto next;
426                                 }
427                                 skb_trim(skb2, len);
428                                 put_unaligned_le16(BIT(15) | BIT(11) | len,
429                                                         skb_push(skb2, 2));
430                                 skb_copy_bits(skb, 0, req->buf, skb->len);
431                                 req->length = skb->len;
432                                 req->complete = eem_cmd_complete;
433                                 req->zero = 1;
434                                 if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC))
435                                         DBG(cdev, "echo response queue fail\n");
436                                 break;
437
438                         case 1:  /* echo response */
439                         case 2:  /* suspend hint */
440                         case 3:  /* response hint */
441                         case 4:  /* response complete hint */
442                         case 5:  /* tickle */
443                         default: /* reserved */
444                                 continue;
445                         }
446                 } else {
447                         u32             crc, crc2;
448                         struct sk_buff  *skb3;
449
450                         /* check for zero-length EEM packet */
451                         if (header == 0)
452                                 continue;
453
454                         /* EEM data packet format:
455                          * b0..13:      length of ethernet frame
456                          * b14:         bmCRC (0 == sentinel, 1 == calculated)
457                          * b15:         bmType (0 == data)
458                          */
459                         len = header & 0x3FFF;
460                         if ((skb->len < len)
461                                         || (len < (ETH_HLEN + ETH_FCS_LEN))) {
462                                 status = -EINVAL;
463                                 goto error;
464                         }
465
466                         /* validate CRC */
467                         crc = get_unaligned_le32(skb->data + len - ETH_FCS_LEN);
468                         if (header & BIT(14)) {
469                                 crc = get_unaligned_le32(skb->data + len
470                                                         - ETH_FCS_LEN);
471                                 crc2 = ~crc32_le(~0,
472                                                 skb->data,
473                                                 skb->len - ETH_FCS_LEN);
474                         } else {
475                                 crc = get_unaligned_be32(skb->data + len
476                                                         - ETH_FCS_LEN);
477                                 crc2 = 0xdeadbeef;
478                         }
479                         if (crc != crc2) {
480                                 DBG(cdev, "invalid EEM CRC\n");
481                                 goto next;
482                         }
483
484                         skb2 = skb_clone(skb, GFP_ATOMIC);
485                         if (unlikely(!skb2)) {
486                                 DBG(cdev, "unable to unframe EEM packet\n");
487                                 continue;
488                         }
489                         skb_trim(skb2, len - ETH_FCS_LEN);
490
491                         skb3 = skb_copy_expand(skb2,
492                                                 NET_IP_ALIGN,
493                                                 0,
494                                                 GFP_ATOMIC);
495                         if (unlikely(!skb3)) {
496                                 DBG(cdev, "unable to realign EEM packet\n");
497                                 dev_kfree_skb_any(skb2);
498                                 continue;
499                         }
500                         dev_kfree_skb_any(skb2);
501                         skb_queue_tail(list, skb3);
502                 }
503 next:
504                 skb_pull(skb, len);
505         } while (skb->len);
506
507 error:
508         dev_kfree_skb_any(skb);
509         return status;
510 }
511
512 /**
513  * eem_bind_config - add CDC Ethernet (EEM) network link to a configuration
514  * @c: the configuration to support the network link
515  * Context: single threaded during gadget setup
516  *
517  * Returns zero on success, else negative errno.
518  *
519  * Caller must have called @gether_setup().  Caller is also responsible
520  * for calling @gether_cleanup() before module unload.
521  */
522 int __init eem_bind_config(struct usb_configuration *c)
523 {
524         struct f_eem    *eem;
525         int             status;
526
527         /* maybe allocate device-global string IDs */
528         if (eem_string_defs[0].id == 0) {
529
530                 /* control interface label */
531                 status = usb_string_id(c->cdev);
532                 if (status < 0)
533                         return status;
534                 eem_string_defs[0].id = status;
535                 eem_intf.iInterface = status;
536         }
537
538         /* allocate and initialize one new instance */
539         eem = kzalloc(sizeof *eem, GFP_KERNEL);
540         if (!eem)
541                 return -ENOMEM;
542
543         eem->port.cdc_filter = DEFAULT_FILTER;
544
545         eem->port.func.name = "cdc_eem";
546         eem->port.func.strings = eem_strings;
547         /* descriptors are per-instance copies */
548         eem->port.func.bind = eem_bind;
549         eem->port.func.unbind = eem_unbind;
550         eem->port.func.set_alt = eem_set_alt;
551         eem->port.func.setup = eem_setup;
552         eem->port.func.disable = eem_disable;
553         eem->port.wrap = eem_wrap;
554         eem->port.unwrap = eem_unwrap;
555         eem->port.header_len = EEM_HLEN;
556
557         status = usb_add_function(c, &eem->port.func);
558         if (status)
559                 kfree(eem);
560         return status;
561 }
562