2 * phonet.c -- USB CDC Phonet host driver
4 * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved.
6 * Author: Rémi Denis-Courmont
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.
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.
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
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>
32 #define PN_MEDIA_USB 0x1B
34 static const unsigned rxq_size
= 17;
37 struct net_device
*dev
;
39 struct usb_interface
*intf
, *data_intf
;
40 struct usb_device
*usb
;
41 unsigned int tx_pipe
, rx_pipe
;
49 struct sk_buff
*rx_skb
;
53 static void tx_complete(struct urb
*req
);
54 static void rx_complete(struct urb
*req
);
57 * Network device callbacks
59 static netdev_tx_t
usbpn_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
61 struct usbpn_dev
*pnd
= netdev_priv(dev
);
62 struct urb
*req
= NULL
;
66 if (skb
->protocol
!= htons(ETH_P_PHONET
))
69 req
= usb_alloc_urb(0, GFP_ATOMIC
);
72 usb_fill_bulk_urb(req
, pnd
->usb
, pnd
->tx_pipe
, skb
->data
, skb
->len
,
74 req
->transfer_flags
= URB_ZERO_PACKET
;
75 err
= usb_submit_urb(req
, GFP_ATOMIC
);
81 spin_lock_irqsave(&pnd
->tx_lock
, flags
);
83 if (pnd
->tx_queue
>= dev
->tx_queue_len
)
84 netif_stop_queue(dev
);
85 spin_unlock_irqrestore(&pnd
->tx_lock
, flags
);
90 dev
->stats
.tx_dropped
++;
94 static void tx_complete(struct urb
*req
)
96 struct sk_buff
*skb
= req
->context
;
97 struct net_device
*dev
= skb
->dev
;
98 struct usbpn_dev
*pnd
= netdev_priv(dev
);
100 switch (req
->status
) {
102 dev
->stats
.tx_bytes
+= skb
->len
;
108 dev
->stats
.tx_aborted_errors
++;
110 dev
->stats
.tx_errors
++;
111 dev_dbg(&dev
->dev
, "TX error (%d)\n", req
->status
);
113 dev
->stats
.tx_packets
++;
115 spin_lock(&pnd
->tx_lock
);
117 netif_wake_queue(dev
);
118 spin_unlock(&pnd
->tx_lock
);
120 dev_kfree_skb_any(skb
);
124 static int rx_submit(struct usbpn_dev
*pnd
, struct urb
*req
, gfp_t gfp_flags
)
126 struct net_device
*dev
= pnd
->dev
;
130 page
= __netdev_alloc_page(dev
, gfp_flags
);
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
);
139 dev_dbg(&dev
->dev
, "RX submit error (%d)\n", err
);
140 netdev_free_page(dev
, page
);
145 static void rx_complete(struct urb
*req
)
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
);
153 switch (req
->status
) {
155 spin_lock_irqsave(&pnd
->rx_lock
, flags
);
158 skb
= pnd
->rx_skb
= netdev_alloc_skb(dev
, 12);
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
);
167 skb_add_rx_frag(skb
, skb_shinfo(skb
)->nr_frags
,
168 page
, 0, req
->actual_length
);
171 if (req
->actual_length
< PAGE_SIZE
)
172 pnd
->rx_skb
= NULL
; /* Last fragment */
175 spin_unlock_irqrestore(&pnd
->rx_lock
, flags
);
177 skb
->protocol
= htons(ETH_P_PHONET
);
178 skb_reset_mac_header(skb
);
181 dev
->stats
.rx_packets
++;
182 dev
->stats
.rx_bytes
+= skb
->len
;
195 dev
->stats
.rx_over_errors
++;
196 dev_dbg(&dev
->dev
, "RX overflow\n");
200 dev
->stats
.rx_crc_errors
++;
204 dev
->stats
.rx_errors
++;
207 netdev_free_page(dev
, page
);
209 rx_submit(pnd
, req
, GFP_ATOMIC
);
212 static int usbpn_close(struct net_device
*dev
);
214 static int usbpn_open(struct net_device
*dev
)
216 struct usbpn_dev
*pnd
= netdev_priv(dev
);
219 unsigned num
= pnd
->data_intf
->cur_altsetting
->desc
.bInterfaceNumber
;
221 err
= usb_set_interface(pnd
->usb
, num
, pnd
->active_setting
);
225 for (i
= 0; i
< rxq_size
; i
++) {
226 struct urb
*req
= usb_alloc_urb(0, GFP_KERNEL
);
228 if (!req
|| rx_submit(pnd
, req
, GFP_KERNEL
)) {
235 netif_wake_queue(dev
);
239 static int usbpn_close(struct net_device
*dev
)
241 struct usbpn_dev
*pnd
= netdev_priv(dev
);
243 unsigned num
= pnd
->data_intf
->cur_altsetting
->desc
.bInterfaceNumber
;
245 netif_stop_queue(dev
);
247 for (i
= 0; i
< rxq_size
; i
++) {
248 struct urb
*req
= pnd
->urbs
[i
];
257 return usb_set_interface(pnd
->usb
, num
, !pnd
->active_setting
);
260 static int usbpn_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
262 struct if_phonet_req
*req
= (struct if_phonet_req
*)ifr
;
265 case SIOCPNGAUTOCONF
:
266 req
->ifr_phonet_autoconf
.device
= PN_DEV_PC
;
267 printk(KERN_CRIT
"device is PN_DEV_PC\n");
273 static int usbpn_set_mtu(struct net_device
*dev
, int new_mtu
)
275 if ((new_mtu
< PHONET_MIN_MTU
) || (new_mtu
> PHONET_MAX_MTU
))
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
,
290 static void usbpn_setup(struct net_device
*dev
)
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
;
301 dev
->tx_queue_len
= 3;
303 dev
->destructor
= free_netdev
;
307 * USB driver callbacks
309 static struct usb_device_id usbpn_ids
[] = {
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,
321 MODULE_DEVICE_TABLE(usb
, usbpn_ids
);
323 static struct usb_driver usbpn_driver
;
325 int usbpn_probe(struct usb_interface
*intf
, const struct usb_device_id
*id
)
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
;
338 data
= intf
->altsetting
->extra
;
339 len
= intf
->altsetting
->extralen
;
345 /* bDescriptorType */
346 if (data
[1] == USB_DT_CS_INTERFACE
) {
347 /* bDescriptorSubType */
349 case USB_CDC_UNION_TYPE
:
350 if (union_header
|| dlen
< 5)
353 (struct usb_cdc_union_desc
*)data
;
356 if (phonet_header
|| dlen
< 5)
359 (struct usb_cdc_header_desc
*)data
;
367 if (!union_header
|| !phonet_header
)
370 data_intf
= usb_ifnum_to_if(usbdev
, union_header
->bSlaveInterface0
);
371 if (data_intf
== NULL
)
373 /* Data interface has one inactive and one active setting */
374 if (data_intf
->num_altsetting
!= 2)
376 if (data_intf
->altsetting
[0].desc
.bNumEndpoints
== 0
377 && data_intf
->altsetting
[1].desc
.bNumEndpoints
== 2)
378 data_desc
= data_intf
->altsetting
+ 1;
380 if (data_intf
->altsetting
[0].desc
.bNumEndpoints
== 2
381 && data_intf
->altsetting
[1].desc
.bNumEndpoints
== 0)
382 data_desc
= data_intf
->altsetting
;
386 dev
= alloc_netdev(sizeof(*pnd
) + sizeof(pnd
->urbs
[0]) * rxq_size
,
387 ifname
, usbpn_setup
);
391 pnd
= netdev_priv(dev
);
392 SET_NETDEV_DEV(dev
, &intf
->dev
);
393 netif_stop_queue(dev
);
396 pnd
->usb
= usb_get_dev(usbdev
);
398 pnd
->data_intf
= data_intf
;
399 spin_lock_init(&pnd
->tx_lock
);
400 spin_lock_init(&pnd
->rx_lock
);
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
);
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
);
413 pnd
->active_setting
= data_desc
- data_intf
->altsetting
;
415 err
= usb_driver_claim_interface(&usbpn_driver
, data_intf
, pnd
);
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
);
424 err
= register_netdev(dev
);
426 usb_driver_release_interface(&usbpn_driver
, data_intf
);
430 dev_dbg(&dev
->dev
, "USB CDC Phonet device found\n");
434 usb_set_intfdata(intf
, NULL
);
439 static void usbpn_disconnect(struct usb_interface
*intf
)
441 struct usbpn_dev
*pnd
= usb_get_intfdata(intf
);
442 struct usb_device
*usb
= pnd
->usb
;
444 if (pnd
->disconnected
)
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
);
454 static struct usb_driver usbpn_driver
= {
455 .name
= "cdc_phonet",
456 .probe
= usbpn_probe
,
457 .disconnect
= usbpn_disconnect
,
458 .id_table
= usbpn_ids
,
461 static int __init
usbpn_init(void)
463 return usb_register(&usbpn_driver
);
466 static void __exit
usbpn_exit(void)
468 usb_deregister(&usbpn_driver
);
471 module_init(usbpn_init
);
472 module_exit(usbpn_exit
);
474 MODULE_AUTHOR("Remi Denis-Courmont");
475 MODULE_DESCRIPTION("USB CDC Phonet host interface");
476 MODULE_LICENSE("GPL");