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