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+w0"
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 int qc_suspend(struct usb_interface *iface, pm_message_t event)
74 struct usbnet *usbnet;
80 usbnet = usb_get_intfdata(iface);
82 if (!usbnet || !usbnet->net) {
83 DBG("failed to get netdevice\n");
87 dev = (struct qcusbnet *)usbnet->data[0];
89 DBG("failed to get QMIDevice\n");
93 if (!(event.event & PM_EVENT_AUTO)) {
94 DBG("device suspended to power level %d\n",
96 qc_setdown(dev, DOWN_DRIVER_SUSPENDED);
98 DBG("device autosuspend\n");
101 if (event.event & PM_EVENT_SUSPEND) {
103 usbnet->udev->reset_resume = 0;
104 iface->dev.power.power_state.event = event.event;
106 usbnet->udev->reset_resume = 1;
109 return usbnet_suspend(iface, event);
112 static int qc_resume(struct usb_interface *iface)
114 struct usbnet *usbnet;
115 struct qcusbnet *dev;
122 usbnet = usb_get_intfdata(iface);
124 if (!usbnet || !usbnet->net) {
125 DBG("failed to get netdevice\n");
129 dev = (struct qcusbnet *)usbnet->data[0];
131 DBG("failed to get QMIDevice\n");
135 oldstate = iface->dev.power.power_state.event;
136 iface->dev.power.power_state.event = PM_EVENT_ON;
137 DBG("resuming from power mode %d\n", oldstate);
139 if (oldstate & PM_EVENT_SUSPEND) {
140 qc_cleardown(dev, DOWN_DRIVER_SUSPENDED);
142 ret = usbnet_resume(iface);
144 DBG("usbnet_resume error %d\n", ret);
148 ret = qc_startread(dev);
150 DBG("qc_startread error %d\n", ret);
154 DBG("nothing to resume\n");
161 static int qcnet_bind(struct usbnet *usbnet, struct usb_interface *iface)
165 struct usb_host_endpoint *endpoint = NULL;
166 struct usb_host_endpoint *in = NULL;
167 struct usb_host_endpoint *out = NULL;
169 if (iface->num_altsetting != 1) {
170 DBG("invalid num_altsetting %u\n", iface->num_altsetting);
174 if (iface->cur_altsetting->desc.bInterfaceNumber != 0
175 && iface->cur_altsetting->desc.bInterfaceNumber != 5) {
176 DBG("invalid interface %d\n",
177 iface->cur_altsetting->desc.bInterfaceNumber);
181 numends = iface->cur_altsetting->desc.bNumEndpoints;
182 for (i = 0; i < numends; i++) {
183 endpoint = iface->cur_altsetting->endpoint + i;
185 DBG("invalid endpoint %u\n", i);
189 if (usb_endpoint_dir_in(&endpoint->desc)
190 && !usb_endpoint_xfer_int(&endpoint->desc)) {
192 } else if (!usb_endpoint_dir_out(&endpoint->desc)) {
198 DBG("invalid endpoints\n");
202 if (usb_set_interface(usbnet->udev,
203 iface->cur_altsetting->desc.bInterfaceNumber, 0)) {
204 DBG("unable to set interface\n");
208 usbnet->in = usb_rcvbulkpipe(usbnet->udev, in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
209 usbnet->out = usb_sndbulkpipe(usbnet->udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
211 DBG("in %x, out %x\n",
212 in->desc.bEndpointAddress,
213 out->desc.bEndpointAddress);
218 static void qcnet_unbind(struct usbnet *usbnet, struct usb_interface *iface)
220 struct qcusbnet *dev = (struct qcusbnet *)usbnet->data[0];
222 netif_carrier_off(usbnet->net);
225 kfree(usbnet->net->netdev_ops);
226 usbnet->net->netdev_ops = NULL;
227 /* drop the list's ref */
231 static void qcnet_bg_complete(struct work_struct *work)
233 unsigned long listflags;
234 struct qcusbnet *dev = container_of(work, struct qcusbnet, complete);
235 BUG_ON(!dev->active);
236 usb_free_urb(dev->active);
238 usb_autopm_put_interface(dev->iface);
239 spin_lock_irqsave(&dev->urbs_lock, listflags);
240 if (!list_empty(&dev->urbs))
241 queue_work(dev->workqueue, &dev->startxmit);
242 spin_unlock_irqrestore(&dev->urbs_lock, listflags);
245 static void qcnet_complete(struct urb *urb)
247 struct qcusbnet *dev = urb->context;
248 queue_work(dev->workqueue, &dev->complete);
251 static void qcnet_bg_txtimeout(struct work_struct *work)
253 struct qcusbnet *dev = container_of(work, struct qcusbnet, txtimeout);
254 struct list_head *node, *tmp;
257 usb_kill_urb(dev->active);
258 list_for_each_safe(node, tmp, &dev->urbs) {
259 req = list_entry(node, struct urbreq, node);
260 usb_free_urb(req->urb);
261 list_del(&req->node);
266 static void qcnet_txtimeout(struct net_device *netdev)
268 struct usbnet *usbnet = netdev_priv(netdev);
269 struct qcusbnet *dev = (struct qcusbnet *)usbnet->data[0];
270 queue_work(dev->workqueue, &dev->txtimeout);
273 static void qcnet_bg_startxmit(struct work_struct *work)
275 unsigned long listflags;
276 struct qcusbnet *dev = container_of(work, struct qcusbnet, startxmit);
277 struct urbreq *req = NULL;
283 status = usb_autopm_get_interface(dev->iface);
285 printk(KERN_WARNING "gobi: can't autoresume interface: %d", status);
286 if (status == -EPERM)
287 qc_suspend(dev->iface, PMSG_SUSPEND);
288 /* We could just drop the packet here, right...? It seems like
289 * if this ever happens, we'll spin, but the old driver did that
291 queue_work(dev->workqueue, &dev->startxmit);
295 spin_lock_irqsave(&dev->urbs_lock, listflags);
296 if (!list_empty(&dev->urbs)) {
297 req = list_first_entry(&dev->urbs, struct urbreq, node);
298 list_del(&req->node);
300 spin_unlock_irqrestore(&dev->urbs_lock, listflags);
302 /* If we hit this case, it means that we added our urb to the
303 * list while there was an urb in flight, and that urb
304 * completed, causing our urb to be submitted; in addition, our
305 * urb completed too, all before we got to schedule this work.
306 * Unlikely, but possible. */
307 usb_autopm_put_interface(dev->iface);
311 dev->active = req->urb;
312 status = usb_submit_urb(dev->active, GFP_KERNEL);
314 printk(KERN_WARNING "gobi: couldn't submit, packet dropped: %d", status);
315 usb_free_urb(dev->active);
317 usb_autopm_put_interface(dev->iface);
323 static int qcnet_startxmit(struct sk_buff *skb, struct net_device *netdev)
325 unsigned long listflags;
328 struct usbnet *usbnet = netdev_priv(netdev);
329 struct qcusbnet *dev = (struct qcusbnet *)usbnet->data[0];
331 if (qc_isdown(dev, DOWN_DRIVER_SUSPENDED)) {
332 DBG("device is suspended\n");
334 return NETDEV_TX_BUSY;
337 req = kmalloc(sizeof(*req), GFP_ATOMIC);
339 DBG("unable to allocate URBList memory\n");
340 return NETDEV_TX_BUSY;
343 req->urb = usb_alloc_urb(0, GFP_ATOMIC);
347 DBG("unable to allocate URB\n");
348 return NETDEV_TX_BUSY;
351 data = kmalloc(skb->len, GFP_ATOMIC);
353 usb_free_urb(req->urb);
355 DBG("unable to allocate URB data\n");
356 return NETDEV_TX_BUSY;
358 memcpy(data, skb->data, skb->len);
360 usb_fill_bulk_urb(req->urb, dev->usbnet->udev, dev->usbnet->out,
361 data, skb->len, qcnet_complete, dev);
363 spin_lock_irqsave(&dev->urbs_lock, listflags);
364 list_add_tail(&req->node, &dev->urbs);
365 spin_unlock_irqrestore(&dev->urbs_lock, listflags);
367 queue_work(dev->workqueue, &dev->startxmit);
369 netdev->trans_start = jiffies;
370 dev_kfree_skb_any(skb);
375 static int qcnet_open(struct net_device *netdev)
378 struct qcusbnet *dev;
379 struct usbnet *usbnet = netdev_priv(netdev);
382 DBG("failed to get usbnet device\n");
386 dev = (struct qcusbnet *)usbnet->data[0];
388 DBG("failed to get QMIDevice\n");
392 qc_cleardown(dev, DOWN_NET_IFACE_STOPPED);
394 status = dev->open(netdev);
396 usb_autopm_put_interface(dev->iface);
399 DBG("no USBNetOpen defined\n");
405 int qcnet_stop(struct net_device *netdev)
407 struct qcusbnet *dev;
408 struct usbnet *usbnet = netdev_priv(netdev);
410 if (!usbnet || !usbnet->net) {
411 DBG("failed to get netdevice\n");
415 dev = (struct qcusbnet *)usbnet->data[0];
417 DBG("failed to get QMIDevice\n");
421 qc_setdown(dev, DOWN_NET_IFACE_STOPPED);
423 if (dev->stop != NULL)
424 return dev->stop(netdev);
428 static const struct driver_info qc_netinfo = {
429 .description = "QCUSBNet Ethernet Device",
432 .unbind = qcnet_unbind,
436 #define MKVIDPID(v, p) \
439 .driver_info = (unsigned long)&qc_netinfo, \
442 static const struct usb_device_id qc_vidpids[] = {
443 MKVIDPID(0x05c6, 0x9215), /* Acer Gobi 2000 */
444 MKVIDPID(0x05c6, 0x9265), /* Asus Gobi 2000 */
445 MKVIDPID(0x16d8, 0x8002), /* CMOTech Gobi 2000 */
446 MKVIDPID(0x413c, 0x8186), /* Dell Gobi 2000 */
447 MKVIDPID(0x1410, 0xa010), /* Entourage Gobi 2000 */
448 MKVIDPID(0x1410, 0xa011), /* Entourage Gobi 2000 */
449 MKVIDPID(0x1410, 0xa012), /* Entourage Gobi 2000 */
450 MKVIDPID(0x1410, 0xa013), /* Entourage Gobi 2000 */
451 MKVIDPID(0x03f0, 0x251d), /* HP Gobi 2000 */
452 MKVIDPID(0x05c6, 0x9205), /* Lenovo Gobi 2000 */
453 MKVIDPID(0x05c6, 0x920b), /* Generic Gobi 2000 */
454 MKVIDPID(0x04da, 0x250f), /* Panasonic Gobi 2000 */
455 MKVIDPID(0x05c6, 0x9245), /* Samsung Gobi 2000 */
456 MKVIDPID(0x1199, 0x9001), /* Sierra Wireless Gobi 2000 */
457 MKVIDPID(0x1199, 0x9002), /* Sierra Wireless Gobi 2000 */
458 MKVIDPID(0x1199, 0x9003), /* Sierra Wireless Gobi 2000 */
459 MKVIDPID(0x1199, 0x9004), /* Sierra Wireless Gobi 2000 */
460 MKVIDPID(0x1199, 0x9005), /* Sierra Wireless Gobi 2000 */
461 MKVIDPID(0x1199, 0x9006), /* Sierra Wireless Gobi 2000 */
462 MKVIDPID(0x1199, 0x9007), /* Sierra Wireless Gobi 2000 */
463 MKVIDPID(0x1199, 0x9008), /* Sierra Wireless Gobi 2000 */
464 MKVIDPID(0x1199, 0x9009), /* Sierra Wireless Gobi 2000 */
465 MKVIDPID(0x1199, 0x900a), /* Sierra Wireless Gobi 2000 */
466 MKVIDPID(0x05c6, 0x9225), /* Sony Gobi 2000 */
467 MKVIDPID(0x05c6, 0x9235), /* Top Global Gobi 2000 */
468 MKVIDPID(0x05c6, 0x9275), /* iRex Technologies Gobi 2000 */
470 MKVIDPID(0x05c6, 0x920d), /* Qualcomm Gobi 3000 */
471 MKVIDPID(0x1410, 0xa021), /* Novatel Gobi 3000 */
472 MKVIDPID(0x413c, 0x8194), /* Dell Gobi 3000 */
473 MKVIDPID(0x12D1, 0x14F1), /* Sony Gobi 3000 */
477 MODULE_DEVICE_TABLE(usb, qc_vidpids);
479 static u8 nibble(unsigned char c)
481 if (likely(isdigit(c)))
484 if (likely(isxdigit(c)))
489 int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids)
492 struct usbnet *usbnet;
493 struct qcusbnet *dev;
494 struct net_device_ops *netdevops;
498 status = usbnet_probe(iface, vidpids);
500 DBG("usbnet_probe failed %d\n", status);
504 usbnet = usb_get_intfdata(iface);
506 if (!usbnet || !usbnet->net) {
507 DBG("failed to get netdevice\n");
511 dev = kmalloc(sizeof(struct qcusbnet), GFP_KERNEL);
513 DBG("failed to allocate device buffers\n");
517 usbnet->data[0] = (unsigned long)dev;
519 dev->usbnet = usbnet;
521 netdevops = kmalloc(sizeof(struct net_device_ops), GFP_KERNEL);
523 DBG("failed to allocate net device ops\n");
526 memcpy(netdevops, usbnet->net->netdev_ops, sizeof(struct net_device_ops));
528 dev->open = netdevops->ndo_open;
529 netdevops->ndo_open = qcnet_open;
530 dev->stop = netdevops->ndo_stop;
531 netdevops->ndo_stop = qcnet_stop;
532 netdevops->ndo_start_xmit = qcnet_startxmit;
533 netdevops->ndo_tx_timeout = qcnet_txtimeout;
535 usbnet->net->netdev_ops = netdevops;
537 memset(&(dev->usbnet->net->stats), 0, sizeof(struct net_device_stats));
540 memset(&(dev->meid), '0', 14);
543 memset(&dev->qmi, 0, sizeof(dev->qmi));
545 dev->qmi.devclass = devclass;
547 kref_init(&dev->refcount);
548 INIT_LIST_HEAD(&dev->node);
549 INIT_LIST_HEAD(&dev->qmi.clients);
550 dev->workqueue = alloc_ordered_workqueue("gobi", 0);
552 spin_lock_init(&dev->urbs_lock);
553 INIT_LIST_HEAD(&dev->urbs);
555 INIT_WORK(&dev->startxmit, qcnet_bg_startxmit);
556 INIT_WORK(&dev->txtimeout, qcnet_bg_txtimeout);
557 INIT_WORK(&dev->complete, qcnet_bg_complete);
559 spin_lock_init(&dev->qmi.clients_lock);
562 qc_setdown(dev, DOWN_NO_NDIS_CONNECTION);
563 qc_setdown(dev, DOWN_NET_IFACE_STOPPED);
565 status = qc_register(dev);
569 mutex_lock(&qcusbnet_lock);
570 /* Give our initial ref to the list */
571 list_add(&dev->node, &qcusbnet_list);
572 mutex_unlock(&qcusbnet_lock);
574 /* After calling qc_register, MEID is valid */
575 addr = &usbnet->net->dev_addr[0];
576 for (i = 0; i < 6; i++)
577 addr[i] = (nibble(dev->meid[i*2+2]) << 4)+
578 nibble(dev->meid[i*2+3]);
579 addr[0] &= 0xfe; /* clear multicast bit */
580 addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
584 EXPORT_SYMBOL_GPL(qcnet_probe);
586 static void qcnet_disconnect(struct usb_interface *intf)
588 struct usbnet *usbnet = usb_get_intfdata(intf);
589 struct qcusbnet *dev = (struct qcusbnet *)usbnet->data[0];
590 struct list_head *node, *tmp;
592 destroy_workqueue(dev->workqueue);
593 list_for_each_safe(node, tmp, &dev->urbs) {
594 req = list_entry(node, struct urbreq, node);
595 usb_free_urb(req->urb);
596 list_del(&req->node);
599 usbnet_disconnect(intf);
602 static struct usb_driver qcusbnet = {
604 .id_table = qc_vidpids,
605 .probe = qcnet_probe,
606 .disconnect = qcnet_disconnect,
607 .suspend = qc_suspend,
609 .supports_autosuspend = true,
612 static int __init modinit(void)
614 devclass = class_create(THIS_MODULE, "QCQMI");
615 if (IS_ERR(devclass)) {
616 DBG("error at class_create %ld\n", PTR_ERR(devclass));
619 printk(KERN_INFO "%s: %s\n", DRIVER_DESC, DRIVER_VERSION);
620 return usb_register(&qcusbnet);
622 module_init(modinit);
624 static void __exit modexit(void)
626 usb_deregister(&qcusbnet);
627 class_destroy(devclass);
629 module_exit(modexit);
631 MODULE_VERSION(DRIVER_VERSION);
632 MODULE_AUTHOR(DRIVER_AUTHOR);
633 MODULE_DESCRIPTION(DRIVER_DESC);
634 MODULE_LICENSE("Dual BSD/GPL");
636 module_param(qcusbnet_debug, bool, S_IRUGO | S_IWUSR);
637 MODULE_PARM_DESC(qcusbnet_debug, "Debugging enabled or not");