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 dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; 97 98 return 0; 99 } 100 101 /* 102 * EEM permits packing multiple Ethernet frames into USB transfers 103 * (a "bundle"), but for TX we don't try to do that. 104 */ 105 static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb, 106 gfp_t flags) 107 { 108 struct sk_buff *skb2 = NULL; 109 u16 len = skb->len; 110 u32 crc = 0; 111 int padlen = 0; 112 113 /* When ((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket) is 114 * zero, stick two bytes of zero length EEM packet on the end. 115 * Else the framework would add invalid single byte padding, 116 * since it can't know whether ZLPs will be handled right by 117 * all the relevant hardware and software. 118 */ 119 if (!((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket)) 120 padlen += 2; 121 122 if (!skb_cloned(skb)) { 123 int headroom = skb_headroom(skb); 124 int tailroom = skb_tailroom(skb); 125 126 if ((tailroom >= ETH_FCS_LEN + padlen) && 127 (headroom >= EEM_HEAD)) 128 goto done; 129 130 if ((headroom + tailroom) 131 > (EEM_HEAD + ETH_FCS_LEN + padlen)) { 132 skb->data = memmove(skb->head + 133 EEM_HEAD, 134 skb->data, 135 skb->len); 136 skb_set_tail_pointer(skb, len); 137 goto done; 138 } 139 } 140 141 skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags); 142 if (!skb2) 143 return NULL; 144 145 dev_kfree_skb_any(skb); 146 skb = skb2; 147 148 done: 149 /* we don't use the "no Ethernet CRC" option */ 150 crc = crc32_le(~0, skb->data, skb->len); 151 crc = ~crc; 152 153 put_unaligned_le32(crc, skb_put(skb, 4)); 154 155 /* EEM packet header format: 156 * b0..13: length of ethernet frame 157 * b14: bmCRC (1 == valid Ethernet CRC) 158 * b15: bmType (0 == data) 159 */ 160 len = skb->len; 161 put_unaligned_le16(BIT(14) | len, skb_push(skb, 2)); 162 163 /* Bundle a zero length EEM packet if needed */ 164 if (padlen) 165 put_unaligned_le16(0, skb_put(skb, 2)); 166 167 return skb; 168 } 169 170 static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) 171 { 172 /* 173 * Our task here is to strip off framing, leaving skb with one 174 * data frame for the usbnet framework code to process. But we 175 * may have received multiple EEM payloads, or command payloads. 176 * So we must process _everything_ as if it's a header, except 177 * maybe the last data payload 178 * 179 * REVISIT the framework needs updating so that when we consume 180 * all payloads (the last or only message was a command, or a 181 * zero length EEM packet) that is not accounted as an rx_error. 182 */ 183 do { 184 struct sk_buff *skb2 = NULL; 185 u16 header; 186 u16 len = 0; 187 188 /* incomplete EEM header? */ 189 if (skb->len < EEM_HEAD) 190 return 0; 191 192 /* 193 * EEM packet header format: 194 * b0..14: EEM type dependent (Data or Command) 195 * b15: bmType 196 */ 197 header = get_unaligned_le16(skb->data); 198 skb_pull(skb, EEM_HEAD); 199 200 /* 201 * The bmType bit helps to denote when EEM 202 * packet is data or command : 203 * bmType = 0 : EEM data payload 204 * bmType = 1 : EEM (link) command 205 */ 206 if (header & BIT(15)) { 207 u16 bmEEMCmd; 208 209 /* 210 * EEM (link) command packet: 211 * b0..10: bmEEMCmdParam 212 * b11..13: bmEEMCmd 213 * b14: bmReserved (must be 0) 214 * b15: 1 (EEM command) 215 */ 216 if (header & BIT(14)) { 217 netdev_dbg(dev->net, "reserved command %04x\n", 218 header); 219 continue; 220 } 221 222 bmEEMCmd = (header >> 11) & 0x7; 223 switch (bmEEMCmd) { 224 225 /* Responding to echo requests is mandatory. */ 226 case 0: /* Echo command */ 227 len = header & 0x7FF; 228 229 /* bogus command? */ 230 if (skb->len < len) 231 return 0; 232 233 skb2 = skb_clone(skb, GFP_ATOMIC); 234 if (unlikely(!skb2)) 235 goto next; 236 skb_trim(skb2, len); 237 put_unaligned_le16(BIT(15) | (1 << 11) | len, 238 skb_push(skb2, 2)); 239 eem_linkcmd(dev, skb2); 240 break; 241 242 /* 243 * Host may choose to ignore hints. 244 * - suspend: peripheral ready to suspend 245 * - response: suggest N millisec polling 246 * - response complete: suggest N sec polling 247 */ 248 case 2: /* Suspend hint */ 249 case 3: /* Response hint */ 250 case 4: /* Response complete hint */ 251 continue; 252 253 /* 254 * Hosts should never receive host-to-peripheral 255 * or reserved command codes; or responses to an 256 * echo command we didn't send. 257 */ 258 case 1: /* Echo response */ 259 case 5: /* Tickle */ 260 default: /* reserved */ 261 netdev_warn(dev->net, 262 "unexpected link command %d\n", 263 bmEEMCmd); 264 continue; 265 } 266 267 } else { 268 u32 crc, crc2; 269 int is_last; 270 271 /* zero length EEM packet? */ 272 if (header == 0) 273 continue; 274 275 /* 276 * EEM data packet header : 277 * b0..13: length of ethernet frame 278 * b14: bmCRC 279 * b15: 0 (EEM data) 280 */ 281 len = header & 0x3FFF; 282 283 /* bogus EEM payload? */ 284 if (skb->len < len) 285 return 0; 286 287 /* bogus ethernet frame? */ 288 if (len < (ETH_HLEN + ETH_FCS_LEN)) 289 goto next; 290 291 /* 292 * Treat the last payload differently: framework 293 * code expects our "fixup" to have stripped off 294 * headers, so "skb" is a data packet (or error). 295 * Else if it's not the last payload, keep "skb" 296 * for further processing. 297 */ 298 is_last = (len == skb->len); 299 if (is_last) 300 skb2 = skb; 301 else { 302 skb2 = skb_clone(skb, GFP_ATOMIC); 303 if (unlikely(!skb2)) 304 return 0; 305 } 306 307 /* 308 * The bmCRC helps to denote when the CRC field in 309 * the Ethernet frame contains a calculated CRC: 310 * bmCRC = 1 : CRC is calculated 311 * bmCRC = 0 : CRC = 0xDEADBEEF 312 */ 313 if (header & BIT(14)) { 314 crc = get_unaligned_le32(skb2->data 315 + len - ETH_FCS_LEN); 316 crc2 = ~crc32_le(~0, skb2->data, skb2->len 317 - ETH_FCS_LEN); 318 } else { 319 crc = get_unaligned_be32(skb2->data 320 + len - ETH_FCS_LEN); 321 crc2 = 0xdeadbeef; 322 } 323 skb_trim(skb2, len - ETH_FCS_LEN); 324 325 if (is_last) 326 return crc == crc2; 327 328 if (unlikely(crc != crc2)) { 329 dev->net->stats.rx_errors++; 330 dev_kfree_skb_any(skb2); 331 } else 332 usbnet_skb_return(dev, skb2); 333 } 334 335 next: 336 skb_pull(skb, len); 337 } while (skb->len); 338 339 return 1; 340 } 341 342 static const struct driver_info eem_info = { 343 .description = "CDC EEM Device", 344 .flags = FLAG_ETHER | FLAG_POINTTOPOINT, 345 .bind = eem_bind, 346 .rx_fixup = eem_rx_fixup, 347 .tx_fixup = eem_tx_fixup, 348 }; 349 350 /*-------------------------------------------------------------------------*/ 351 352 static const struct usb_device_id products[] = { 353 { 354 USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_EEM, 355 USB_CDC_PROTO_EEM), 356 .driver_info = (unsigned long) &eem_info, 357 }, 358 { 359 /* EMPTY == end of list */ 360 }, 361 }; 362 MODULE_DEVICE_TABLE(usb, products); 363 364 static struct usb_driver eem_driver = { 365 .name = "cdc_eem", 366 .id_table = products, 367 .probe = usbnet_probe, 368 .disconnect = usbnet_disconnect, 369 .suspend = usbnet_suspend, 370 .resume = usbnet_resume, 371 }; 372 373 module_usb_driver(eem_driver); 374 375 MODULE_AUTHOR("Omar Laazimani <omar.oberthur@gmail.com>"); 376 MODULE_DESCRIPTION("USB CDC EEM"); 377 MODULE_LICENSE("GPL"); 378