08d55b6bf272bc5293a8a8d059d54d652aca27e1
[linux-drm-fsl-dcu.git] / drivers / net / usb / cdc_eem.c
1 /*
2  * USB CDC EEM network interface driver
3  * Copyright (C) 2009 Oberthur Technologies
4  * by Omar Laazimani, Olivier Condemine
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/netdevice.h>
24 #include <linux/etherdevice.h>
25 #include <linux/ctype.h>
26 #include <linux/ethtool.h>
27 #include <linux/workqueue.h>
28 #include <linux/mii.h>
29 #include <linux/usb.h>
30 #include <linux/crc32.h>
31 #include <linux/usb/cdc.h>
32 #include <linux/usb/usbnet.h>
33 #include <linux/gfp.h>
34 #include <linux/if_vlan.h>
35
36
37 /*
38  * This driver is an implementation of the CDC "Ethernet Emulation
39  * Model" (EEM) specification, which encapsulates Ethernet frames
40  * for transport over USB using a simpler USB device model than the
41  * previous CDC "Ethernet Control Model" (ECM, or "CDC Ethernet").
42  *
43  * For details, see www.usb.org/developers/devclass_docs/CDC_EEM10.pdf
44  *
45  * This version has been tested with GIGAntIC WuaoW SIM Smart Card on 2.6.24,
46  * 2.6.27 and 2.6.30rc2 kernel.
47  * It has also been validated on Openmoko Om 2008.12 (based on 2.6.24 kernel).
48  * build on 23-April-2009
49  */
50
51 #define EEM_HEAD        2               /* 2 byte header */
52
53 /*-------------------------------------------------------------------------*/
54
55 static void eem_linkcmd_complete(struct urb *urb)
56 {
57         dev_kfree_skb(urb->context);
58         usb_free_urb(urb);
59 }
60
61 static void eem_linkcmd(struct usbnet *dev, struct sk_buff *skb)
62 {
63         struct urb              *urb;
64         int                     status;
65
66         urb = usb_alloc_urb(0, GFP_ATOMIC);
67         if (!urb)
68                 goto fail;
69
70         usb_fill_bulk_urb(urb, dev->udev, dev->out,
71                         skb->data, skb->len, eem_linkcmd_complete, skb);
72
73         status = usb_submit_urb(urb, GFP_ATOMIC);
74         if (status) {
75                 usb_free_urb(urb);
76 fail:
77                 dev_kfree_skb(skb);
78                 netdev_warn(dev->net, "link cmd failure\n");
79                 return;
80         }
81 }
82
83 static int eem_bind(struct usbnet *dev, struct usb_interface *intf)
84 {
85         int status = 0;
86
87         status = usbnet_get_endpoints(dev, intf);
88         if (status < 0) {
89                 usb_set_intfdata(intf, NULL);
90                 usb_driver_release_interface(driver_of(intf), intf);
91                 return status;
92         }
93
94         /* no jumbogram (16K) support for now */
95
96         dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN;
97         dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
98
99         return 0;
100 }
101
102 /*
103  * EEM permits packing multiple Ethernet frames into USB transfers
104  * (a "bundle"), but for TX we don't try to do that.
105  */
106 static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
107                                        gfp_t flags)
108 {
109         struct sk_buff  *skb2 = NULL;
110         u16             len = skb->len;
111         u32             crc = 0;
112         int             padlen = 0;
113
114         /* When ((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket) is
115          * zero, stick two bytes of zero length EEM packet on the end.
116          * Else the framework would add invalid single byte padding,
117          * since it can't know whether ZLPs will be handled right by
118          * all the relevant hardware and software.
119          */
120         if (!((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket))
121                 padlen += 2;
122
123         if (!skb_cloned(skb)) {
124                 int     headroom = skb_headroom(skb);
125                 int     tailroom = skb_tailroom(skb);
126
127                 if ((tailroom >= ETH_FCS_LEN + padlen) &&
128                     (headroom >= EEM_HEAD))
129                         goto done;
130
131                 if ((headroom + tailroom)
132                                 > (EEM_HEAD + ETH_FCS_LEN + padlen)) {
133                         skb->data = memmove(skb->head +
134                                         EEM_HEAD,
135                                         skb->data,
136                                         skb->len);
137                         skb_set_tail_pointer(skb, len);
138                         goto done;
139                 }
140         }
141
142         skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags);
143         if (!skb2)
144                 return NULL;
145
146         dev_kfree_skb_any(skb);
147         skb = skb2;
148
149 done:
150         /* we don't use the "no Ethernet CRC" option */
151         crc = crc32_le(~0, skb->data, skb->len);
152         crc = ~crc;
153
154         put_unaligned_le32(crc, skb_put(skb, 4));
155
156         /* EEM packet header format:
157          * b0..13:      length of ethernet frame
158          * b14:         bmCRC (1 == valid Ethernet CRC)
159          * b15:         bmType (0 == data)
160          */
161         len = skb->len;
162         put_unaligned_le16(BIT(14) | len, skb_push(skb, 2));
163
164         /* Bundle a zero length EEM packet if needed */
165         if (padlen)
166                 put_unaligned_le16(0, skb_put(skb, 2));
167
168         return skb;
169 }
170
171 static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
172 {
173         /*
174          * Our task here is to strip off framing, leaving skb with one
175          * data frame for the usbnet framework code to process.  But we
176          * may have received multiple EEM payloads, or command payloads.
177          * So we must process _everything_ as if it's a header, except
178          * maybe the last data payload
179          *
180          * REVISIT the framework needs updating so that when we consume
181          * all payloads (the last or only message was a command, or a
182          * zero length EEM packet) that is not accounted as an rx_error.
183          */
184         do {
185                 struct sk_buff  *skb2 = NULL;
186                 u16             header;
187                 u16             len = 0;
188
189                 /* incomplete EEM header? */
190                 if (skb->len < EEM_HEAD)
191                         return 0;
192
193                 /*
194                  * EEM packet header format:
195                  * b0..14:      EEM type dependent (Data or Command)
196                  * b15:         bmType
197                  */
198                 header = get_unaligned_le16(skb->data);
199                 skb_pull(skb, EEM_HEAD);
200
201                 /*
202                  * The bmType bit helps to denote when EEM
203                  * packet is data or command :
204                  *      bmType = 0      : EEM data payload
205                  *      bmType = 1      : EEM (link) command
206                  */
207                 if (header & BIT(15)) {
208                         u16     bmEEMCmd;
209
210                         /*
211                          * EEM (link) command packet:
212                          * b0..10:      bmEEMCmdParam
213                          * b11..13:     bmEEMCmd
214                          * b14:         bmReserved (must be 0)
215                          * b15:         1 (EEM command)
216                          */
217                         if (header & BIT(14)) {
218                                 netdev_dbg(dev->net, "reserved command %04x\n",
219                                            header);
220                                 continue;
221                         }
222
223                         bmEEMCmd = (header >> 11) & 0x7;
224                         switch (bmEEMCmd) {
225
226                         /* Responding to echo requests is mandatory. */
227                         case 0:         /* Echo command */
228                                 len = header & 0x7FF;
229
230                                 /* bogus command? */
231                                 if (skb->len < len)
232                                         return 0;
233
234                                 skb2 = skb_clone(skb, GFP_ATOMIC);
235                                 if (unlikely(!skb2))
236                                         goto next;
237                                 skb_trim(skb2, len);
238                                 put_unaligned_le16(BIT(15) | (1 << 11) | len,
239                                                 skb_push(skb2, 2));
240                                 eem_linkcmd(dev, skb2);
241                                 break;
242
243                         /*
244                          * Host may choose to ignore hints.
245                          *  - suspend: peripheral ready to suspend
246                          *  - response: suggest N millisec polling
247                          *  - response complete: suggest N sec polling
248                          *
249                          * Suspend is reported and maybe heeded.
250                          */
251                         case 2:         /* Suspend hint */
252                                 usbnet_device_suggests_idle(dev);
253                                 continue;
254                         case 3:         /* Response hint */
255                         case 4:         /* Response complete hint */
256                                 continue;
257
258                         /*
259                          * Hosts should never receive host-to-peripheral
260                          * or reserved command codes; or responses to an
261                          * echo command we didn't send.
262                          */
263                         case 1:         /* Echo response */
264                         case 5:         /* Tickle */
265                         default:        /* reserved */
266                                 netdev_warn(dev->net,
267                                             "unexpected link command %d\n",
268                                             bmEEMCmd);
269                                 continue;
270                         }
271
272                 } else {
273                         u32     crc, crc2;
274                         int     is_last;
275
276                         /* zero length EEM packet? */
277                         if (header == 0)
278                                 continue;
279
280                         /*
281                          * EEM data packet header :
282                          * b0..13:      length of ethernet frame
283                          * b14:         bmCRC
284                          * b15:         0 (EEM data)
285                          */
286                         len = header & 0x3FFF;
287
288                         /* bogus EEM payload? */
289                         if (skb->len < len)
290                                 return 0;
291
292                         /* bogus ethernet frame? */
293                         if (len < (ETH_HLEN + ETH_FCS_LEN))
294                                 goto next;
295
296                         /*
297                          * Treat the last payload differently: framework
298                          * code expects our "fixup" to have stripped off
299                          * headers, so "skb" is a data packet (or error).
300                          * Else if it's not the last payload, keep "skb"
301                          * for further processing.
302                          */
303                         is_last = (len == skb->len);
304                         if (is_last)
305                                 skb2 = skb;
306                         else {
307                                 skb2 = skb_clone(skb, GFP_ATOMIC);
308                                 if (unlikely(!skb2))
309                                         return 0;
310                         }
311
312                         /*
313                          * The bmCRC helps to denote when the CRC field in
314                          * the Ethernet frame contains a calculated CRC:
315                          *      bmCRC = 1       : CRC is calculated
316                          *      bmCRC = 0       : CRC = 0xDEADBEEF
317                          */
318                         if (header & BIT(14)) {
319                                 crc = get_unaligned_le32(skb2->data
320                                                 + len - ETH_FCS_LEN);
321                                 crc2 = ~crc32_le(~0, skb2->data, skb2->len
322                                                 - ETH_FCS_LEN);
323                         } else {
324                                 crc = get_unaligned_be32(skb2->data
325                                                 + len - ETH_FCS_LEN);
326                                 crc2 = 0xdeadbeef;
327                         }
328                         skb_trim(skb2, len - ETH_FCS_LEN);
329
330                         if (is_last)
331                                 return crc == crc2;
332
333                         if (unlikely(crc != crc2)) {
334                                 dev->net->stats.rx_errors++;
335                                 dev_kfree_skb_any(skb2);
336                         } else
337                                 usbnet_skb_return(dev, skb2);
338                 }
339
340 next:
341                 skb_pull(skb, len);
342         } while (skb->len);
343
344         return 1;
345 }
346
347 static const struct driver_info eem_info = {
348         .description =  "CDC EEM Device",
349         .flags =        FLAG_ETHER | FLAG_POINTTOPOINT,
350         .bind =         eem_bind,
351         .rx_fixup =     eem_rx_fixup,
352         .tx_fixup =     eem_tx_fixup,
353 };
354
355 /*-------------------------------------------------------------------------*/
356
357 static const struct usb_device_id products[] = {
358 {
359         USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_EEM,
360                         USB_CDC_PROTO_EEM),
361         .driver_info = (unsigned long) &eem_info,
362 },
363 {
364         /* EMPTY == end of list */
365 },
366 };
367 MODULE_DEVICE_TABLE(usb, products);
368
369 static struct usb_driver eem_driver = {
370         .name =         "cdc_eem",
371         .id_table =     products,
372         .probe =        usbnet_probe,
373         .disconnect =   usbnet_disconnect,
374         .suspend =      usbnet_suspend,
375         .resume =       usbnet_resume,
376         .disable_hub_initiated_lpm = 1,
377 };
378
379 module_usb_driver(eem_driver);
380
381 MODULE_AUTHOR("Omar Laazimani <omar.oberthur@gmail.com>");
382 MODULE_DESCRIPTION("USB CDC EEM");
383 MODULE_LICENSE("GPL");