1 /* qcusbnet.c - gobi network device
2 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #include "qmidevice.h"
24 #include <linux/module.h>
25 #include <linux/ctype.h>
27 #define DRIVER_VERSION "1.0.110+google"
28 #define DRIVER_AUTHOR "Qualcomm Innovation Center"
29 #define DRIVER_DESC "gobi"
31 static LIST_HEAD(qcusbnet_list);
32 static DEFINE_MUTEX(qcusbnet_lock);
35 static struct class *devclass;
37 static void free_dev(struct kref *ref)
39 struct qcusbnet *dev = container_of(ref, struct qcusbnet, refcount);
44 void qcusbnet_put(struct qcusbnet *dev)
46 mutex_lock(&qcusbnet_lock);
47 kref_put(&dev->refcount, free_dev);
48 mutex_unlock(&qcusbnet_lock);
51 struct qcusbnet *qcusbnet_get(struct qcusbnet *key)
53 /* Given a putative qcusbnet struct, return either the struct itself
54 * (with a ref taken) if the struct is still visible, or NULL if it's
55 * not. This prevents object-visibility races where someone is looking
56 * up an object as the last ref gets dropped; dropping the last ref and
57 * removing the object from the list are atomic with respect to getting
59 struct qcusbnet *entry;
60 mutex_lock(&qcusbnet_lock);
61 list_for_each_entry(entry, &qcusbnet_list, node) {
63 kref_get(&entry->refcount);
64 mutex_unlock(&qcusbnet_lock);
68 mutex_unlock(&qcusbnet_lock);
72 static void wake_worker(struct worker *worker)
74 atomic_inc(&worker->work_count);
75 wake_up(&worker->waitq);
78 int qc_suspend(struct usb_interface *iface, pm_message_t event)
80 struct usbnet *usbnet;
86 usbnet = usb_get_intfdata(iface);
88 if (!usbnet || !usbnet->net) {
89 DBG("failed to get netdevice\n");
93 dev = (struct qcusbnet *)usbnet->data[0];
95 DBG("failed to get QMIDevice\n");
99 if (!(event.event & PM_EVENT_AUTO)) {
100 DBG("device suspended to power level %d\n",
102 qc_setdown(dev, DOWN_DRIVER_SUSPENDED);
104 DBG("device autosuspend\n");
107 if (event.event & PM_EVENT_SUSPEND) {
109 usbnet->udev->reset_resume = 0;
110 iface->dev.power.power_state.event = event.event;
112 usbnet->udev->reset_resume = 1;
115 return usbnet_suspend(iface, event);
118 static int qc_resume(struct usb_interface *iface)
120 struct usbnet *usbnet;
121 struct qcusbnet *dev;
128 usbnet = usb_get_intfdata(iface);
130 if (!usbnet || !usbnet->net) {
131 DBG("failed to get netdevice\n");
135 dev = (struct qcusbnet *)usbnet->data[0];
137 DBG("failed to get QMIDevice\n");
141 oldstate = iface->dev.power.power_state.event;
142 iface->dev.power.power_state.event = PM_EVENT_ON;
143 DBG("resuming from power mode %d\n", oldstate);
145 if (oldstate & PM_EVENT_SUSPEND) {
146 qc_cleardown(dev, DOWN_DRIVER_SUSPENDED);
148 ret = usbnet_resume(iface);
150 DBG("usbnet_resume error %d\n", ret);
154 ret = qc_startread(dev);
156 DBG("qc_startread error %d\n", ret);
160 wake_worker(&dev->worker);
162 DBG("nothing to resume\n");
169 static int qcnet_bind(struct usbnet *usbnet, struct usb_interface *iface)
173 struct usb_host_endpoint *endpoint = NULL;
174 struct usb_host_endpoint *in = NULL;
175 struct usb_host_endpoint *out = NULL;
177 if (iface->num_altsetting != 1) {
178 DBG("invalid num_altsetting %u\n", iface->num_altsetting);
182 if (iface->cur_altsetting->desc.bInterfaceNumber != 0
183 && iface->cur_altsetting->desc.bInterfaceNumber != 5) {
184 DBG("invalid interface %d\n",
185 iface->cur_altsetting->desc.bInterfaceNumber);
189 numends = iface->cur_altsetting->desc.bNumEndpoints;
190 for (i = 0; i < numends; i++) {
191 endpoint = iface->cur_altsetting->endpoint + i;
193 DBG("invalid endpoint %u\n", i);
197 if (usb_endpoint_dir_in(&endpoint->desc)
198 && !usb_endpoint_xfer_int(&endpoint->desc)) {
200 } else if (!usb_endpoint_dir_out(&endpoint->desc)) {
206 DBG("invalid endpoints\n");
210 if (usb_set_interface(usbnet->udev,
211 iface->cur_altsetting->desc.bInterfaceNumber, 0)) {
212 DBG("unable to set interface\n");
216 usbnet->in = usb_rcvbulkpipe(usbnet->udev, in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
217 usbnet->out = usb_sndbulkpipe(usbnet->udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
219 DBG("in %x, out %x\n",
220 in->desc.bEndpointAddress,
221 out->desc.bEndpointAddress);
226 static void qcnet_unbind(struct usbnet *usbnet, struct usb_interface *iface)
228 struct qcusbnet *dev = (struct qcusbnet *)usbnet->data[0];
230 netif_carrier_off(usbnet->net);
233 kfree(usbnet->net->netdev_ops);
234 usbnet->net->netdev_ops = NULL;
235 /* drop the list's ref */
239 static void qcnet_urbhook(struct urb *urb)
242 struct worker *worker = urb->context;
244 DBG("bad context\n");
249 DBG("urb finished with error %d\n", urb->status);
252 spin_lock_irqsave(&worker->active_lock, flags);
253 worker->active = ERR_PTR(-EAGAIN);
254 spin_unlock_irqrestore(&worker->active_lock, flags);
255 /* XXX-fix race against qcnet_stop()? */
260 static void qcnet_txtimeout(struct net_device *netdev)
262 struct list_head *node, *tmp;
263 struct qcusbnet *dev;
264 struct worker *worker;
266 unsigned long activeflags, listflags;
267 struct usbnet *usbnet = netdev_priv(netdev);
269 if (!usbnet || !usbnet->net) {
270 DBG("failed to get usbnet device\n");
274 dev = (struct qcusbnet *)usbnet->data[0];
276 DBG("failed to get QMIDevice\n");
279 worker = &dev->worker;
283 spin_lock_irqsave(&worker->active_lock, activeflags);
285 usb_kill_urb(worker->active);
286 spin_unlock_irqrestore(&worker->active_lock, activeflags);
288 spin_lock_irqsave(&worker->urbs_lock, listflags);
289 list_for_each_safe(node, tmp, &worker->urbs) {
290 req = list_entry(node, struct urbreq, node);
291 usb_free_urb(req->urb);
292 list_del(&req->node);
295 spin_unlock_irqrestore(&worker->urbs_lock, listflags);
300 static int worker_should_wake(struct worker *worker)
302 if (kthread_should_stop())
304 /* This is safe only because we are the only place that decrements this
306 if (atomic_read(&worker->work_count))
311 static int qcnet_worker(void *arg)
313 struct list_head *node, *tmp;
314 unsigned long activeflags, listflags;
317 struct usb_device *usbdev;
318 struct worker *worker = arg;
320 DBG("passed null pointer\n");
324 usbdev = interface_to_usbdev(worker->iface);
326 DBG("traffic thread started\n");
328 while (!kthread_should_stop()) {
329 wait_event(worker->waitq, worker_should_wake(worker));
331 if (kthread_should_stop())
333 atomic_dec(&worker->work_count);
335 spin_lock_irqsave(&worker->active_lock, activeflags);
336 if (IS_ERR(worker->active) && PTR_ERR(worker->active) == -EAGAIN) {
337 worker->active = NULL;
338 spin_unlock_irqrestore(&worker->active_lock, activeflags);
339 usb_autopm_put_interface(worker->iface);
340 spin_lock_irqsave(&worker->active_lock, activeflags);
343 if (worker->active) {
344 spin_unlock_irqrestore(&worker->active_lock, activeflags);
348 spin_lock_irqsave(&worker->urbs_lock, listflags);
349 if (list_empty(&worker->urbs)) {
350 spin_unlock_irqrestore(&worker->urbs_lock, listflags);
351 spin_unlock_irqrestore(&worker->active_lock, activeflags);
355 req = list_first_entry(&worker->urbs, struct urbreq, node);
356 list_del(&req->node);
357 spin_unlock_irqrestore(&worker->urbs_lock, listflags);
359 worker->active = req->urb;
360 spin_unlock_irqrestore(&worker->active_lock, activeflags);
362 status = usb_autopm_get_interface(worker->iface);
364 DBG("unable to autoresume interface: %d\n", status);
365 if (status == -EPERM) {
366 qc_suspend(worker->iface, PMSG_SUSPEND);
369 spin_lock_irqsave(&worker->urbs_lock, listflags);
370 list_add(&req->node, &worker->urbs);
371 spin_unlock_irqrestore(&worker->urbs_lock, listflags);
373 spin_lock_irqsave(&worker->active_lock, activeflags);
374 worker->active = NULL;
375 spin_unlock_irqrestore(&worker->active_lock, activeflags);
380 status = usb_submit_urb(worker->active, GFP_KERNEL);
382 DBG("Failed to submit URB: %d. Packet dropped\n", status);
383 spin_lock_irqsave(&worker->active_lock, activeflags);
384 usb_free_urb(worker->active);
385 worker->active = NULL;
386 spin_unlock_irqrestore(&worker->active_lock, activeflags);
387 usb_autopm_put_interface(worker->iface);
394 spin_lock_irqsave(&worker->active_lock, activeflags);
395 if (worker->active) {
396 usb_kill_urb(worker->active);
398 spin_unlock_irqrestore(&worker->active_lock, activeflags);
400 spin_lock_irqsave(&worker->urbs_lock, listflags);
401 list_for_each_safe(node, tmp, &worker->urbs) {
402 req = list_entry(node, struct urbreq, node);
403 usb_free_urb(req->urb);
404 list_del(&req->node);
407 spin_unlock_irqrestore(&worker->urbs_lock, listflags);
409 DBG("traffic thread exiting\n");
410 worker->thread = NULL;
414 static int qcnet_startxmit(struct sk_buff *skb, struct net_device *netdev)
416 unsigned long listflags;
417 struct qcusbnet *dev;
418 struct worker *worker;
421 struct usbnet *usbnet = netdev_priv(netdev);
425 if (!usbnet || !usbnet->net) {
426 DBG("failed to get usbnet device\n");
427 return NETDEV_TX_BUSY;
430 dev = (struct qcusbnet *)usbnet->data[0];
432 DBG("failed to get QMIDevice\n");
433 return NETDEV_TX_BUSY;
435 worker = &dev->worker;
437 if (qc_isdown(dev, DOWN_DRIVER_SUSPENDED)) {
438 DBG("device is suspended\n");
440 return NETDEV_TX_BUSY;
443 req = kmalloc(sizeof(*req), GFP_ATOMIC);
445 DBG("unable to allocate URBList memory\n");
446 return NETDEV_TX_BUSY;
449 req->urb = usb_alloc_urb(0, GFP_ATOMIC);
453 DBG("unable to allocate URB\n");
454 return NETDEV_TX_BUSY;
457 data = kmalloc(skb->len, GFP_ATOMIC);
459 usb_free_urb(req->urb);
461 DBG("unable to allocate URB data\n");
462 return NETDEV_TX_BUSY;
464 memcpy(data, skb->data, skb->len);
466 usb_fill_bulk_urb(req->urb, dev->usbnet->udev, dev->usbnet->out,
467 data, skb->len, qcnet_urbhook, worker);
469 spin_lock_irqsave(&worker->urbs_lock, listflags);
470 list_add_tail(&req->node, &worker->urbs);
471 spin_unlock_irqrestore(&worker->urbs_lock, listflags);
475 netdev->trans_start = jiffies;
476 dev_kfree_skb_any(skb);
481 static int qcnet_open(struct net_device *netdev)
484 struct qcusbnet *dev;
485 struct usbnet *usbnet = netdev_priv(netdev);
488 DBG("failed to get usbnet device\n");
492 dev = (struct qcusbnet *)usbnet->data[0];
494 DBG("failed to get QMIDevice\n");
500 dev->worker.iface = dev->iface;
501 INIT_LIST_HEAD(&dev->worker.urbs);
502 dev->worker.active = NULL;
503 spin_lock_init(&dev->worker.urbs_lock);
504 spin_lock_init(&dev->worker.active_lock);
505 atomic_set(&dev->worker.work_count, 0);
506 init_waitqueue_head(&dev->worker.waitq);
508 dev->worker.thread = kthread_run(qcnet_worker, &dev->worker, "qcnet_worker");
509 if (IS_ERR(dev->worker.thread)) {
510 DBG("AutoPM thread creation error\n");
511 return PTR_ERR(dev->worker.thread);
514 qc_cleardown(dev, DOWN_NET_IFACE_STOPPED);
516 status = dev->open(netdev);
518 usb_autopm_put_interface(dev->iface);
521 DBG("no USBNetOpen defined\n");
527 int qcnet_stop(struct net_device *netdev)
529 struct qcusbnet *dev;
530 struct usbnet *usbnet = netdev_priv(netdev);
532 if (!usbnet || !usbnet->net) {
533 DBG("failed to get netdevice\n");
537 dev = (struct qcusbnet *)usbnet->data[0];
539 DBG("failed to get QMIDevice\n");
543 qc_setdown(dev, DOWN_NET_IFACE_STOPPED);
544 kthread_stop(dev->worker.thread);
545 DBG("thread stopped\n");
547 if (dev->stop != NULL)
548 return dev->stop(netdev);
552 static const struct driver_info qc_netinfo = {
553 .description = "QCUSBNet Ethernet Device",
556 .unbind = qcnet_unbind,
560 #define MKVIDPID(v, p) \
563 .driver_info = (unsigned long)&qc_netinfo, \
566 static const struct usb_device_id qc_vidpids[] = {
567 MKVIDPID(0x05c6, 0x9215), /* Acer Gobi 2000 */
568 MKVIDPID(0x05c6, 0x9265), /* Asus Gobi 2000 */
569 MKVIDPID(0x16d8, 0x8002), /* CMOTech Gobi 2000 */
570 MKVIDPID(0x413c, 0x8186), /* Dell Gobi 2000 */
571 MKVIDPID(0x1410, 0xa010), /* Entourage Gobi 2000 */
572 MKVIDPID(0x1410, 0xa011), /* Entourage Gobi 2000 */
573 MKVIDPID(0x1410, 0xa012), /* Entourage Gobi 2000 */
574 MKVIDPID(0x1410, 0xa013), /* Entourage Gobi 2000 */
575 MKVIDPID(0x03f0, 0x251d), /* HP Gobi 2000 */
576 MKVIDPID(0x05c6, 0x9205), /* Lenovo Gobi 2000 */
577 MKVIDPID(0x05c6, 0x920b), /* Generic Gobi 2000 */
578 MKVIDPID(0x04da, 0x250f), /* Panasonic Gobi 2000 */
579 MKVIDPID(0x05c6, 0x9245), /* Samsung Gobi 2000 */
580 MKVIDPID(0x1199, 0x9001), /* Sierra Wireless Gobi 2000 */
581 MKVIDPID(0x1199, 0x9002), /* Sierra Wireless Gobi 2000 */
582 MKVIDPID(0x1199, 0x9003), /* Sierra Wireless Gobi 2000 */
583 MKVIDPID(0x1199, 0x9004), /* Sierra Wireless Gobi 2000 */
584 MKVIDPID(0x1199, 0x9005), /* Sierra Wireless Gobi 2000 */
585 MKVIDPID(0x1199, 0x9006), /* Sierra Wireless Gobi 2000 */
586 MKVIDPID(0x1199, 0x9007), /* Sierra Wireless Gobi 2000 */
587 MKVIDPID(0x1199, 0x9008), /* Sierra Wireless Gobi 2000 */
588 MKVIDPID(0x1199, 0x9009), /* Sierra Wireless Gobi 2000 */
589 MKVIDPID(0x1199, 0x900a), /* Sierra Wireless Gobi 2000 */
590 MKVIDPID(0x05c6, 0x9225), /* Sony Gobi 2000 */
591 MKVIDPID(0x05c6, 0x9235), /* Top Global Gobi 2000 */
592 MKVIDPID(0x05c6, 0x9275), /* iRex Technologies Gobi 2000 */
594 MKVIDPID(0x05c6, 0x920d), /* Qualcomm Gobi 3000 */
595 MKVIDPID(0x1410, 0xa021), /* Novatel Gobi 3000 */
596 MKVIDPID(0x413c, 0x8194), /* Dell Gobi 3000 */
597 MKVIDPID(0x12D1, 0x14F1), /* Sony Gobi 3000 */
601 MODULE_DEVICE_TABLE(usb, qc_vidpids);
603 static u8 nibble(unsigned char c)
605 if (likely(isdigit(c)))
608 if (likely(isxdigit(c)))
613 int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids)
616 struct usbnet *usbnet;
617 struct qcusbnet *dev;
618 struct net_device_ops *netdevops;
622 status = usbnet_probe(iface, vidpids);
624 DBG("usbnet_probe failed %d\n", status);
628 usbnet = usb_get_intfdata(iface);
630 if (!usbnet || !usbnet->net) {
631 DBG("failed to get netdevice\n");
635 dev = kmalloc(sizeof(struct qcusbnet), GFP_KERNEL);
637 DBG("failed to allocate device buffers\n");
641 usbnet->data[0] = (unsigned long)dev;
643 dev->usbnet = usbnet;
645 netdevops = kmalloc(sizeof(struct net_device_ops), GFP_KERNEL);
647 DBG("failed to allocate net device ops\n");
650 memcpy(netdevops, usbnet->net->netdev_ops, sizeof(struct net_device_ops));
652 dev->open = netdevops->ndo_open;
653 netdevops->ndo_open = qcnet_open;
654 dev->stop = netdevops->ndo_stop;
655 netdevops->ndo_stop = qcnet_stop;
656 netdevops->ndo_start_xmit = qcnet_startxmit;
657 netdevops->ndo_tx_timeout = qcnet_txtimeout;
659 usbnet->net->netdev_ops = netdevops;
661 memset(&(dev->usbnet->net->stats), 0, sizeof(struct net_device_stats));
664 memset(&(dev->meid), '0', 14);
667 memset(&dev->qmi, 0, sizeof(dev->qmi));
669 dev->qmi.devclass = devclass;
671 kref_init(&dev->refcount);
672 INIT_LIST_HEAD(&dev->node);
673 INIT_LIST_HEAD(&dev->qmi.clients);
674 atomic_set(&dev->worker.work_count, 0);
675 init_waitqueue_head(&dev->worker.waitq);
676 spin_lock_init(&dev->qmi.clients_lock);
679 qc_setdown(dev, DOWN_NO_NDIS_CONNECTION);
680 qc_setdown(dev, DOWN_NET_IFACE_STOPPED);
682 status = qc_register(dev);
686 mutex_lock(&qcusbnet_lock);
687 /* Give our initial ref to the list */
688 list_add(&dev->node, &qcusbnet_list);
689 mutex_unlock(&qcusbnet_lock);
691 /* After calling qc_register, MEID is valid */
692 addr = &usbnet->net->dev_addr[0];
693 for (i = 0; i < 6; i++)
694 addr[i] = (nibble(dev->meid[i*2+2]) << 4)+
695 nibble(dev->meid[i*2+3]);
696 addr[0] &= 0xfe; /* clear multicast bit */
697 addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
701 EXPORT_SYMBOL_GPL(qcnet_probe);
703 static struct usb_driver qcusbnet = {
705 .id_table = qc_vidpids,
706 .probe = qcnet_probe,
707 .disconnect = usbnet_disconnect,
708 .suspend = qc_suspend,
710 .supports_autosuspend = true,
713 static int __init modinit(void)
715 devclass = class_create(THIS_MODULE, "QCQMI");
716 if (IS_ERR(devclass)) {
717 DBG("error at class_create %ld\n", PTR_ERR(devclass));
720 printk(KERN_INFO "%s: %s\n", DRIVER_DESC, DRIVER_VERSION);
721 return usb_register(&qcusbnet);
723 module_init(modinit);
725 static void __exit modexit(void)
727 usb_deregister(&qcusbnet);
728 class_destroy(devclass);
730 module_exit(modexit);
732 MODULE_VERSION(DRIVER_VERSION);
733 MODULE_AUTHOR(DRIVER_AUTHOR);
734 MODULE_DESCRIPTION(DRIVER_DESC);
735 MODULE_LICENSE("Dual BSD/GPL");
737 module_param(qcusbnet_debug, bool, S_IRUGO | S_IWUSR);
738 MODULE_PARM_DESC(qcusbnet_debug, "Debugging enabled or not");