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 return status; 88 89 /* no jumbogram (16K) support for now */ 90 91 dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN; 92 dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; 93 94 return 0; 95 } 96 97 /* 98 * EEM permits packing multiple Ethernet frames into USB transfers 99 * (a "bundle"), but for TX we don't try to do that. 100 */ 101 static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb, 102 gfp_t flags) 103 { 104 struct sk_buff *skb2 = NULL; 105 u16 len = skb->len; 106 u32 crc = 0; 107 int padlen = 0; 108 109 /* When ((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket) is 110 * zero, stick two bytes of zero length EEM packet on the end. 111 * Else the framework would add invalid single byte padding, 112 * since it can't know whether ZLPs will be handled right by 113 * all the relevant hardware and software. 114 */ 115 if (!((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket)) 116 padlen += 2; 117 118 if (!skb_cloned(skb)) { 119 int headroom = skb_headroom(skb); 120 int tailroom = skb_tailroom(skb); 121 122 if ((tailroom >= ETH_FCS_LEN + padlen) && 123 (headroom >= EEM_HEAD)) 124 goto done; 125 126 if ((headroom + tailroom) 127 > (EEM_HEAD + ETH_FCS_LEN + padlen)) { 128 skb->data = memmove(skb->head + 129 EEM_HEAD, 130 skb->data, 131 skb->len); 132 skb_set_tail_pointer(skb, len); 133 goto done; 134 } 135 } 136 137 skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags); 138 if (!skb2) 139 return NULL; 140 141 dev_kfree_skb_any(skb); 142 skb = skb2; 143 144 done: 145 /* we don't use the "no Ethernet CRC" option */ 146 crc = crc32_le(~0, skb->data, skb->len); 147 crc = ~crc; 148 149 put_unaligned_le32(crc, skb_put(skb, 4)); 150 151 /* EEM packet header format: 152 * b0..13: length of ethernet frame 153 * b14: bmCRC (1 == valid Ethernet CRC) 154 * b15: bmType (0 == data) 155 */ 156 len = skb->len; 157 put_unaligned_le16(BIT(14) | len, skb_push(skb, 2)); 158 159 /* Bundle a zero length EEM packet if needed */ 160 if (padlen) 161 put_unaligned_le16(0, skb_put(skb, 2)); 162 163 return skb; 164 } 165 166 static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) 167 { 168 /* 169 * Our task here is to strip off framing, leaving skb with one 170 * data frame for the usbnet framework code to process. But we 171 * may have received multiple EEM payloads, or command payloads. 172 * So we must process _everything_ as if it's a header, except 173 * maybe the last data payload 174 * 175 * REVISIT the framework needs updating so that when we consume 176 * all payloads (the last or only message was a command, or a 177 * zero length EEM packet) that is not accounted as an rx_error. 178 */ 179 do { 180 struct sk_buff *skb2 = NULL; 181 u16 header; 182 u16 len = 0; 183 184 /* incomplete EEM header? */ 185 if (skb->len < EEM_HEAD) 186 return 0; 187 188 /* 189 * EEM packet header format: 190 * b0..14: EEM type dependent (Data or Command) 191 * b15: bmType 192 */ 193 header = get_unaligned_le16(skb->data); 194 skb_pull(skb, EEM_HEAD); 195 196 /* 197 * The bmType bit helps to denote when EEM 198 * packet is data or command : 199 * bmType = 0 : EEM data payload 200 * bmType = 1 : EEM (link) command 201 */ 202 if (header & BIT(15)) { 203 u16 bmEEMCmd; 204 205 /* 206 * EEM (link) command packet: 207 * b0..10: bmEEMCmdParam 208 * b11..13: bmEEMCmd 209 * b14: bmReserved (must be 0) 210 * b15: 1 (EEM command) 211 */ 212 if (header & BIT(14)) { 213 netdev_dbg(dev->net, "reserved command %04x\n", 214 header); 215 continue; 216 } 217 218 bmEEMCmd = (header >> 11) & 0x7; 219 switch (bmEEMCmd) { 220 221 /* Responding to echo requests is mandatory. */ 222 case 0: /* Echo command */ 223 len = header & 0x7FF; 224 225 /* bogus command? */ 226 if (skb->len < len) 227 return 0; 228 229 skb2 = skb_clone(skb, GFP_ATOMIC); 230 if (unlikely(!skb2)) 231 goto next; 232 skb_trim(skb2, len); 233 put_unaligned_le16(BIT(15) | (1 << 11) | len, 234 skb_push(skb2, 2)); 235 eem_linkcmd(dev, skb2); 236 break; 237 238 /* 239 * Host may choose to ignore hints. 240 * - suspend: peripheral ready to suspend 241 * - response: suggest N millisec polling 242 * - response complete: suggest N sec polling 243 * 244 * Suspend is reported and maybe heeded. 245 */ 246 case 2: /* Suspend hint */ 247 usbnet_device_suggests_idle(dev); 248 continue; 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 .disable_hub_initiated_lpm = 1, 372 }; 373 374 module_usb_driver(eem_driver); 375 376 MODULE_AUTHOR("Omar Laazimani <omar.oberthur@gmail.com>"); 377 MODULE_DESCRIPTION("USB CDC EEM"); 378 MODULE_LICENSE("GPL"); 379