1 /* 2 * phonet.c -- USB CDC Phonet host driver 3 * 4 * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved. 5 * 6 * Author: Rémi Denis-Courmont 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * version 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 */ 22 23 #include <linux/kernel.h> 24 #include <linux/module.h> 25 #include <linux/usb.h> 26 #include <linux/usb/cdc.h> 27 #include <linux/netdevice.h> 28 #include <linux/if_arp.h> 29 #include <linux/if_phonet.h> 30 #include <linux/phonet.h> 31 32 #define PN_MEDIA_USB 0x1B 33 34 static const unsigned rxq_size = 17; 35 36 struct usbpn_dev { 37 struct net_device *dev; 38 39 struct usb_interface *intf, *data_intf; 40 struct usb_device *usb; 41 unsigned int tx_pipe, rx_pipe; 42 u8 active_setting; 43 u8 disconnected; 44 45 unsigned tx_queue; 46 spinlock_t tx_lock; 47 48 spinlock_t rx_lock; 49 struct sk_buff *rx_skb; 50 struct urb *urbs[0]; 51 }; 52 53 static void tx_complete(struct urb *req); 54 static void rx_complete(struct urb *req); 55 56 /* 57 * Network device callbacks 58 */ 59 static netdev_tx_t usbpn_xmit(struct sk_buff *skb, struct net_device *dev) 60 { 61 struct usbpn_dev *pnd = netdev_priv(dev); 62 struct urb *req = NULL; 63 unsigned long flags; 64 int err; 65 66 if (skb->protocol != htons(ETH_P_PHONET)) 67 goto drop; 68 69 req = usb_alloc_urb(0, GFP_ATOMIC); 70 if (!req) 71 goto drop; 72 usb_fill_bulk_urb(req, pnd->usb, pnd->tx_pipe, skb->data, skb->len, 73 tx_complete, skb); 74 req->transfer_flags = URB_ZERO_PACKET; 75 err = usb_submit_urb(req, GFP_ATOMIC); 76 if (err) { 77 usb_free_urb(req); 78 goto drop; 79 } 80 81 spin_lock_irqsave(&pnd->tx_lock, flags); 82 pnd->tx_queue++; 83 if (pnd->tx_queue >= dev->tx_queue_len) 84 netif_stop_queue(dev); 85 spin_unlock_irqrestore(&pnd->tx_lock, flags); 86 return NETDEV_TX_OK; 87 88 drop: 89 dev_kfree_skb(skb); 90 dev->stats.tx_dropped++; 91 return NETDEV_TX_OK; 92 } 93 94 static void tx_complete(struct urb *req) 95 { 96 struct sk_buff *skb = req->context; 97 struct net_device *dev = skb->dev; 98 struct usbpn_dev *pnd = netdev_priv(dev); 99 100 switch (req->status) { 101 case 0: 102 dev->stats.tx_bytes += skb->len; 103 break; 104 105 case -ENOENT: 106 case -ECONNRESET: 107 case -ESHUTDOWN: 108 dev->stats.tx_aborted_errors++; 109 default: 110 dev->stats.tx_errors++; 111 dev_dbg(&dev->dev, "TX error (%d)\n", req->status); 112 } 113 dev->stats.tx_packets++; 114 115 spin_lock(&pnd->tx_lock); 116 pnd->tx_queue--; 117 netif_wake_queue(dev); 118 spin_unlock(&pnd->tx_lock); 119 120 dev_kfree_skb_any(skb); 121 usb_free_urb(req); 122 } 123 124 static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags) 125 { 126 struct net_device *dev = pnd->dev; 127 struct page *page; 128 int err; 129 130 page = __netdev_alloc_page(dev, gfp_flags); 131 if (!page) 132 return -ENOMEM; 133 134 usb_fill_bulk_urb(req, pnd->usb, pnd->rx_pipe, page_address(page), 135 PAGE_SIZE, rx_complete, dev); 136 req->transfer_flags = 0; 137 err = usb_submit_urb(req, gfp_flags); 138 if (unlikely(err)) { 139 dev_dbg(&dev->dev, "RX submit error (%d)\n", err); 140 netdev_free_page(dev, page); 141 } 142 return err; 143 } 144 145 static void rx_complete(struct urb *req) 146 { 147 struct net_device *dev = req->context; 148 struct usbpn_dev *pnd = netdev_priv(dev); 149 struct page *page = virt_to_page(req->transfer_buffer); 150 struct sk_buff *skb; 151 unsigned long flags; 152 153 switch (req->status) { 154 case 0: 155 spin_lock_irqsave(&pnd->rx_lock, flags); 156 skb = pnd->rx_skb; 157 if (!skb) { 158 skb = pnd->rx_skb = netdev_alloc_skb(dev, 12); 159 if (likely(skb)) { 160 /* Can't use pskb_pull() on page in IRQ */ 161 memcpy(skb_put(skb, 1), page_address(page), 1); 162 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, 163 page, 1, req->actual_length); 164 page = NULL; 165 } 166 } else { 167 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, 168 page, 0, req->actual_length); 169 page = NULL; 170 } 171 if (req->actual_length < PAGE_SIZE) 172 pnd->rx_skb = NULL; /* Last fragment */ 173 else 174 skb = NULL; 175 spin_unlock_irqrestore(&pnd->rx_lock, flags); 176 if (skb) { 177 skb->protocol = htons(ETH_P_PHONET); 178 skb_reset_mac_header(skb); 179 __skb_pull(skb, 1); 180 skb->dev = dev; 181 dev->stats.rx_packets++; 182 dev->stats.rx_bytes += skb->len; 183 184 netif_rx(skb); 185 } 186 goto resubmit; 187 188 case -ENOENT: 189 case -ECONNRESET: 190 case -ESHUTDOWN: 191 req = NULL; 192 break; 193 194 case -EOVERFLOW: 195 dev->stats.rx_over_errors++; 196 dev_dbg(&dev->dev, "RX overflow\n"); 197 break; 198 199 case -EILSEQ: 200 dev->stats.rx_crc_errors++; 201 break; 202 } 203 204 dev->stats.rx_errors++; 205 resubmit: 206 if (page) 207 netdev_free_page(dev, page); 208 if (req) 209 rx_submit(pnd, req, GFP_ATOMIC); 210 } 211 212 static int usbpn_close(struct net_device *dev); 213 214 static int usbpn_open(struct net_device *dev) 215 { 216 struct usbpn_dev *pnd = netdev_priv(dev); 217 int err; 218 unsigned i; 219 unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; 220 221 err = usb_set_interface(pnd->usb, num, pnd->active_setting); 222 if (err) 223 return err; 224 225 for (i = 0; i < rxq_size; i++) { 226 struct urb *req = usb_alloc_urb(0, GFP_KERNEL); 227 228 if (!req || rx_submit(pnd, req, GFP_KERNEL)) { 229 usbpn_close(dev); 230 return -ENOMEM; 231 } 232 pnd->urbs[i] = req; 233 } 234 235 netif_wake_queue(dev); 236 return 0; 237 } 238 239 static int usbpn_close(struct net_device *dev) 240 { 241 struct usbpn_dev *pnd = netdev_priv(dev); 242 unsigned i; 243 unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; 244 245 netif_stop_queue(dev); 246 247 for (i = 0; i < rxq_size; i++) { 248 struct urb *req = pnd->urbs[i]; 249 250 if (!req) 251 continue; 252 usb_kill_urb(req); 253 usb_free_urb(req); 254 pnd->urbs[i] = NULL; 255 } 256 257 return usb_set_interface(pnd->usb, num, !pnd->active_setting); 258 } 259 260 static int usbpn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 261 { 262 struct if_phonet_req *req = (struct if_phonet_req *)ifr; 263 264 switch (cmd) { 265 case SIOCPNGAUTOCONF: 266 req->ifr_phonet_autoconf.device = PN_DEV_PC; 267 printk(KERN_CRIT"device is PN_DEV_PC\n"); 268 return 0; 269 } 270 return -ENOIOCTLCMD; 271 } 272 273 static int usbpn_set_mtu(struct net_device *dev, int new_mtu) 274 { 275 if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU)) 276 return -EINVAL; 277 278 dev->mtu = new_mtu; 279 return 0; 280 } 281 282 static const struct net_device_ops usbpn_ops = { 283 .ndo_open = usbpn_open, 284 .ndo_stop = usbpn_close, 285 .ndo_start_xmit = usbpn_xmit, 286 .ndo_do_ioctl = usbpn_ioctl, 287 .ndo_change_mtu = usbpn_set_mtu, 288 }; 289 290 static void usbpn_setup(struct net_device *dev) 291 { 292 dev->features = 0; 293 dev->netdev_ops = &usbpn_ops, 294 dev->header_ops = &phonet_header_ops; 295 dev->type = ARPHRD_PHONET; 296 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 297 dev->mtu = PHONET_MAX_MTU; 298 dev->hard_header_len = 1; 299 dev->dev_addr[0] = PN_MEDIA_USB; 300 dev->addr_len = 1; 301 dev->tx_queue_len = 3; 302 303 dev->destructor = free_netdev; 304 } 305 306 /* 307 * USB driver callbacks 308 */ 309 static struct usb_device_id usbpn_ids[] = { 310 { 311 .match_flags = USB_DEVICE_ID_MATCH_VENDOR 312 | USB_DEVICE_ID_MATCH_INT_CLASS 313 | USB_DEVICE_ID_MATCH_INT_SUBCLASS, 314 .idVendor = 0x0421, /* Nokia */ 315 .bInterfaceClass = USB_CLASS_COMM, 316 .bInterfaceSubClass = 0xFE, 317 }, 318 { }, 319 }; 320 321 MODULE_DEVICE_TABLE(usb, usbpn_ids); 322 323 static struct usb_driver usbpn_driver; 324 325 int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) 326 { 327 static const char ifname[] = "usbpn%d"; 328 const struct usb_cdc_union_desc *union_header = NULL; 329 const struct usb_cdc_header_desc *phonet_header = NULL; 330 const struct usb_host_interface *data_desc; 331 struct usb_interface *data_intf; 332 struct usb_device *usbdev = interface_to_usbdev(intf); 333 struct net_device *dev; 334 struct usbpn_dev *pnd; 335 u8 *data; 336 int len, err; 337 338 data = intf->altsetting->extra; 339 len = intf->altsetting->extralen; 340 while (len >= 3) { 341 u8 dlen = data[0]; 342 if (dlen < 3) 343 return -EINVAL; 344 345 /* bDescriptorType */ 346 if (data[1] == USB_DT_CS_INTERFACE) { 347 /* bDescriptorSubType */ 348 switch (data[2]) { 349 case USB_CDC_UNION_TYPE: 350 if (union_header || dlen < 5) 351 break; 352 union_header = 353 (struct usb_cdc_union_desc *)data; 354 break; 355 case 0xAB: 356 if (phonet_header || dlen < 5) 357 break; 358 phonet_header = 359 (struct usb_cdc_header_desc *)data; 360 break; 361 } 362 } 363 data += dlen; 364 len -= dlen; 365 } 366 367 if (!union_header || !phonet_header) 368 return -EINVAL; 369 370 data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0); 371 if (data_intf == NULL) 372 return -ENODEV; 373 /* Data interface has one inactive and one active setting */ 374 if (data_intf->num_altsetting != 2) 375 return -EINVAL; 376 if (data_intf->altsetting[0].desc.bNumEndpoints == 0 377 && data_intf->altsetting[1].desc.bNumEndpoints == 2) 378 data_desc = data_intf->altsetting + 1; 379 else 380 if (data_intf->altsetting[0].desc.bNumEndpoints == 2 381 && data_intf->altsetting[1].desc.bNumEndpoints == 0) 382 data_desc = data_intf->altsetting; 383 else 384 return -EINVAL; 385 386 dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size, 387 ifname, usbpn_setup); 388 if (!dev) 389 return -ENOMEM; 390 391 pnd = netdev_priv(dev); 392 SET_NETDEV_DEV(dev, &intf->dev); 393 netif_stop_queue(dev); 394 395 pnd->dev = dev; 396 pnd->usb = usb_get_dev(usbdev); 397 pnd->intf = intf; 398 pnd->data_intf = data_intf; 399 spin_lock_init(&pnd->tx_lock); 400 spin_lock_init(&pnd->rx_lock); 401 /* Endpoints */ 402 if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { 403 pnd->rx_pipe = usb_rcvbulkpipe(usbdev, 404 data_desc->endpoint[0].desc.bEndpointAddress); 405 pnd->tx_pipe = usb_sndbulkpipe(usbdev, 406 data_desc->endpoint[1].desc.bEndpointAddress); 407 } else { 408 pnd->rx_pipe = usb_rcvbulkpipe(usbdev, 409 data_desc->endpoint[1].desc.bEndpointAddress); 410 pnd->tx_pipe = usb_sndbulkpipe(usbdev, 411 data_desc->endpoint[0].desc.bEndpointAddress); 412 } 413 pnd->active_setting = data_desc - data_intf->altsetting; 414 415 err = usb_driver_claim_interface(&usbpn_driver, data_intf, pnd); 416 if (err) 417 goto out; 418 419 /* Force inactive mode until the network device is brought UP */ 420 usb_set_interface(usbdev, union_header->bSlaveInterface0, 421 !pnd->active_setting); 422 usb_set_intfdata(intf, pnd); 423 424 err = register_netdev(dev); 425 if (err) { 426 usb_driver_release_interface(&usbpn_driver, data_intf); 427 goto out; 428 } 429 430 dev_dbg(&dev->dev, "USB CDC Phonet device found\n"); 431 return 0; 432 433 out: 434 usb_set_intfdata(intf, NULL); 435 free_netdev(dev); 436 return err; 437 } 438 439 static void usbpn_disconnect(struct usb_interface *intf) 440 { 441 struct usbpn_dev *pnd = usb_get_intfdata(intf); 442 struct usb_device *usb = pnd->usb; 443 444 if (pnd->disconnected) 445 return; 446 447 pnd->disconnected = 1; 448 usb_driver_release_interface(&usbpn_driver, 449 (pnd->intf == intf) ? pnd->data_intf : pnd->intf); 450 unregister_netdev(pnd->dev); 451 usb_put_dev(usb); 452 } 453 454 static struct usb_driver usbpn_driver = { 455 .name = "cdc_phonet", 456 .probe = usbpn_probe, 457 .disconnect = usbpn_disconnect, 458 .id_table = usbpn_ids, 459 }; 460 461 static int __init usbpn_init(void) 462 { 463 return usb_register(&usbpn_driver); 464 } 465 466 static void __exit usbpn_exit(void) 467 { 468 usb_deregister(&usbpn_driver); 469 } 470 471 module_init(usbpn_init); 472 module_exit(usbpn_exit); 473 474 MODULE_AUTHOR("Remi Denis-Courmont"); 475 MODULE_DESCRIPTION("USB CDC Phonet host interface"); 476 MODULE_LICENSE("GPL"); 477