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, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include <linux/module.h> 21 #include <linux/netdevice.h> 22 #include <linux/etherdevice.h> 23 #include <linux/ctype.h> 24 #include <linux/ethtool.h> 25 #include <linux/workqueue.h> 26 #include <linux/mii.h> 27 #include <linux/usb.h> 28 #include <linux/crc32.h> 29 #include <linux/usb/cdc.h> 30 #include <linux/usb/usbnet.h> 31 #include <linux/gfp.h> 32 #include <linux/if_vlan.h> 33 34 35 /* 36 * This driver is an implementation of the CDC "Ethernet Emulation 37 * Model" (EEM) specification, which encapsulates Ethernet frames 38 * for transport over USB using a simpler USB device model than the 39 * previous CDC "Ethernet Control Model" (ECM, or "CDC Ethernet"). 40 * 41 * For details, see www.usb.org/developers/devclass_docs/CDC_EEM10.pdf 42 * 43 * This version has been tested with GIGAntIC WuaoW SIM Smart Card on 2.6.24, 44 * 2.6.27 and 2.6.30rc2 kernel. 45 * It has also been validated on Openmoko Om 2008.12 (based on 2.6.24 kernel). 46 * build on 23-April-2009 47 */ 48 49 #define EEM_HEAD 2 /* 2 byte header */ 50 51 /*-------------------------------------------------------------------------*/ 52 53 static void eem_linkcmd_complete(struct urb *urb) 54 { 55 dev_kfree_skb(urb->context); 56 usb_free_urb(urb); 57 } 58 59 static void eem_linkcmd(struct usbnet *dev, struct sk_buff *skb) 60 { 61 struct urb *urb; 62 int status; 63 64 urb = usb_alloc_urb(0, GFP_ATOMIC); 65 if (!urb) 66 goto fail; 67 68 usb_fill_bulk_urb(urb, dev->udev, dev->out, 69 skb->data, skb->len, eem_linkcmd_complete, skb); 70 71 status = usb_submit_urb(urb, GFP_ATOMIC); 72 if (status) { 73 usb_free_urb(urb); 74 fail: 75 dev_kfree_skb(skb); 76 netdev_warn(dev->net, "link cmd failure\n"); 77 return; 78 } 79 } 80 81 static int eem_bind(struct usbnet *dev, struct usb_interface *intf) 82 { 83 int status = 0; 84 85 status = usbnet_get_endpoints(dev, intf); 86 if (status < 0) { 87 usb_set_intfdata(intf, NULL); 88 usb_driver_release_interface(driver_of(intf), intf); 89 return status; 90 } 91 92 /* no jumbogram (16K) support for now */ 93 94 dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN; 95 dev->hard_mtu = dev->net->mtu + dev->net->hard_header_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 dependent (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 * Suspend is reported and maybe heeded. 248 */ 249 case 2: /* Suspend hint */ 250 usbnet_device_suggests_idle(dev); 251 continue; 252 case 3: /* Response hint */ 253 case 4: /* Response complete hint */ 254 continue; 255 256 /* 257 * Hosts should never receive host-to-peripheral 258 * or reserved command codes; or responses to an 259 * echo command we didn't send. 260 */ 261 case 1: /* Echo response */ 262 case 5: /* Tickle */ 263 default: /* reserved */ 264 netdev_warn(dev->net, 265 "unexpected link command %d\n", 266 bmEEMCmd); 267 continue; 268 } 269 270 } else { 271 u32 crc, crc2; 272 int is_last; 273 274 /* zero length EEM packet? */ 275 if (header == 0) 276 continue; 277 278 /* 279 * EEM data packet header : 280 * b0..13: length of ethernet frame 281 * b14: bmCRC 282 * b15: 0 (EEM data) 283 */ 284 len = header & 0x3FFF; 285 286 /* bogus EEM payload? */ 287 if (skb->len < len) 288 return 0; 289 290 /* bogus ethernet frame? */ 291 if (len < (ETH_HLEN + ETH_FCS_LEN)) 292 goto next; 293 294 /* 295 * Treat the last payload differently: framework 296 * code expects our "fixup" to have stripped off 297 * headers, so "skb" is a data packet (or error). 298 * Else if it's not the last payload, keep "skb" 299 * for further processing. 300 */ 301 is_last = (len == skb->len); 302 if (is_last) 303 skb2 = skb; 304 else { 305 skb2 = skb_clone(skb, GFP_ATOMIC); 306 if (unlikely(!skb2)) 307 return 0; 308 } 309 310 /* 311 * The bmCRC helps to denote when the CRC field in 312 * the Ethernet frame contains a calculated CRC: 313 * bmCRC = 1 : CRC is calculated 314 * bmCRC = 0 : CRC = 0xDEADBEEF 315 */ 316 if (header & BIT(14)) { 317 crc = get_unaligned_le32(skb2->data 318 + len - ETH_FCS_LEN); 319 crc2 = ~crc32_le(~0, skb2->data, skb2->len 320 - ETH_FCS_LEN); 321 } else { 322 crc = get_unaligned_be32(skb2->data 323 + len - ETH_FCS_LEN); 324 crc2 = 0xdeadbeef; 325 } 326 skb_trim(skb2, len - ETH_FCS_LEN); 327 328 if (is_last) 329 return crc == crc2; 330 331 if (unlikely(crc != crc2)) { 332 dev->net->stats.rx_errors++; 333 dev_kfree_skb_any(skb2); 334 } else 335 usbnet_skb_return(dev, skb2); 336 } 337 338 next: 339 skb_pull(skb, len); 340 } while (skb->len); 341 342 return 1; 343 } 344 345 static const struct driver_info eem_info = { 346 .description = "CDC EEM Device", 347 .flags = FLAG_ETHER | FLAG_POINTTOPOINT, 348 .bind = eem_bind, 349 .rx_fixup = eem_rx_fixup, 350 .tx_fixup = eem_tx_fixup, 351 }; 352 353 /*-------------------------------------------------------------------------*/ 354 355 static const struct usb_device_id products[] = { 356 { 357 USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_EEM, 358 USB_CDC_PROTO_EEM), 359 .driver_info = (unsigned long) &eem_info, 360 }, 361 { 362 /* EMPTY == end of list */ 363 }, 364 }; 365 MODULE_DEVICE_TABLE(usb, products); 366 367 static struct usb_driver eem_driver = { 368 .name = "cdc_eem", 369 .id_table = products, 370 .probe = usbnet_probe, 371 .disconnect = usbnet_disconnect, 372 .suspend = usbnet_suspend, 373 .resume = usbnet_resume, 374 .disable_hub_initiated_lpm = 1, 375 }; 376 377 module_usb_driver(eem_driver); 378 379 MODULE_AUTHOR("Omar Laazimani <omar.oberthur@gmail.com>"); 380 MODULE_DESCRIPTION("USB CDC EEM"); 381 MODULE_LICENSE("GPL"); 382