1 // SPDX-License-Identifier: GPL-2.0-only
3 * phonet.c -- USB CDC Phonet host driver
5 * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved.
7 * Author: RĂ©mi Denis-Courmont
10 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/gfp.h>
14 #include <linux/usb.h>
15 #include <linux/usb/cdc.h>
16 #include <linux/netdevice.h>
17 #include <linux/if_arp.h>
18 #include <linux/if_phonet.h>
19 #include <linux/phonet.h>
21 #define PN_MEDIA_USB 0x1B
23 static const unsigned rxq_size
= 17;
26 struct net_device
*dev
;
28 struct usb_interface
*intf
, *data_intf
;
29 struct usb_device
*usb
;
30 unsigned int tx_pipe
, rx_pipe
;
38 struct sk_buff
*rx_skb
;
42 static void tx_complete(struct urb
*req
);
43 static void rx_complete(struct urb
*req
);
46 * Network device callbacks
48 static netdev_tx_t
usbpn_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
50 struct usbpn_dev
*pnd
= netdev_priv(dev
);
51 struct urb
*req
= NULL
;
55 if (skb
->protocol
!= htons(ETH_P_PHONET
))
58 req
= usb_alloc_urb(0, GFP_ATOMIC
);
61 usb_fill_bulk_urb(req
, pnd
->usb
, pnd
->tx_pipe
, skb
->data
, skb
->len
,
63 req
->transfer_flags
= URB_ZERO_PACKET
;
64 err
= usb_submit_urb(req
, GFP_ATOMIC
);
70 spin_lock_irqsave(&pnd
->tx_lock
, flags
);
72 if (pnd
->tx_queue
>= dev
->tx_queue_len
)
73 netif_stop_queue(dev
);
74 spin_unlock_irqrestore(&pnd
->tx_lock
, flags
);
79 dev
->stats
.tx_dropped
++;
83 static void tx_complete(struct urb
*req
)
85 struct sk_buff
*skb
= req
->context
;
86 struct net_device
*dev
= skb
->dev
;
87 struct usbpn_dev
*pnd
= netdev_priv(dev
);
88 int status
= req
->status
;
93 dev
->stats
.tx_bytes
+= skb
->len
;
99 dev
->stats
.tx_aborted_errors
++;
102 dev
->stats
.tx_errors
++;
103 dev_dbg(&dev
->dev
, "TX error (%d)\n", status
);
105 dev
->stats
.tx_packets
++;
107 spin_lock_irqsave(&pnd
->tx_lock
, flags
);
109 netif_wake_queue(dev
);
110 spin_unlock_irqrestore(&pnd
->tx_lock
, flags
);
112 dev_kfree_skb_any(skb
);
116 static int rx_submit(struct usbpn_dev
*pnd
, struct urb
*req
, gfp_t gfp_flags
)
118 struct net_device
*dev
= pnd
->dev
;
122 page
= __dev_alloc_page(gfp_flags
| __GFP_NOMEMALLOC
);
126 usb_fill_bulk_urb(req
, pnd
->usb
, pnd
->rx_pipe
, page_address(page
),
127 PAGE_SIZE
, rx_complete
, dev
);
128 req
->transfer_flags
= 0;
129 err
= usb_submit_urb(req
, gfp_flags
);
131 dev_dbg(&dev
->dev
, "RX submit error (%d)\n", err
);
137 static void rx_complete(struct urb
*req
)
139 struct net_device
*dev
= req
->context
;
140 struct usbpn_dev
*pnd
= netdev_priv(dev
);
141 struct page
*page
= virt_to_page(req
->transfer_buffer
);
144 int status
= req
->status
;
148 spin_lock_irqsave(&pnd
->rx_lock
, flags
);
151 skb
= pnd
->rx_skb
= netdev_alloc_skb(dev
, 12);
153 /* Can't use pskb_pull() on page in IRQ */
154 skb_put_data(skb
, page_address(page
), 1);
155 skb_add_rx_frag(skb
, skb_shinfo(skb
)->nr_frags
,
156 page
, 1, req
->actual_length
,
161 skb_add_rx_frag(skb
, skb_shinfo(skb
)->nr_frags
,
162 page
, 0, req
->actual_length
,
166 if (req
->actual_length
< PAGE_SIZE
)
167 pnd
->rx_skb
= NULL
; /* Last fragment */
170 spin_unlock_irqrestore(&pnd
->rx_lock
, flags
);
172 skb
->protocol
= htons(ETH_P_PHONET
);
173 skb_reset_mac_header(skb
);
176 dev
->stats
.rx_packets
++;
177 dev
->stats
.rx_bytes
+= skb
->len
;
190 dev
->stats
.rx_over_errors
++;
191 dev_dbg(&dev
->dev
, "RX overflow\n");
195 dev
->stats
.rx_crc_errors
++;
199 dev
->stats
.rx_errors
++;
204 rx_submit(pnd
, req
, GFP_ATOMIC
);
207 static int usbpn_close(struct net_device
*dev
);
209 static int usbpn_open(struct net_device
*dev
)
211 struct usbpn_dev
*pnd
= netdev_priv(dev
);
214 unsigned num
= pnd
->data_intf
->cur_altsetting
->desc
.bInterfaceNumber
;
216 err
= usb_set_interface(pnd
->usb
, num
, pnd
->active_setting
);
220 for (i
= 0; i
< rxq_size
; i
++) {
221 struct urb
*req
= usb_alloc_urb(0, GFP_KERNEL
);
223 if (!req
|| rx_submit(pnd
, req
, GFP_KERNEL
)) {
231 netif_wake_queue(dev
);
235 static int usbpn_close(struct net_device
*dev
)
237 struct usbpn_dev
*pnd
= netdev_priv(dev
);
239 unsigned num
= pnd
->data_intf
->cur_altsetting
->desc
.bInterfaceNumber
;
241 netif_stop_queue(dev
);
243 for (i
= 0; i
< rxq_size
; i
++) {
244 struct urb
*req
= pnd
->urbs
[i
];
253 return usb_set_interface(pnd
->usb
, num
, !pnd
->active_setting
);
256 static int usbpn_siocdevprivate(struct net_device
*dev
, struct ifreq
*ifr
,
257 void __user
*data
, int cmd
)
259 struct if_phonet_req
*req
= (struct if_phonet_req
*)ifr
;
262 case SIOCPNGAUTOCONF
:
263 req
->ifr_phonet_autoconf
.device
= PN_DEV_PC
;
269 static const struct net_device_ops usbpn_ops
= {
270 .ndo_open
= usbpn_open
,
271 .ndo_stop
= usbpn_close
,
272 .ndo_start_xmit
= usbpn_xmit
,
273 .ndo_siocdevprivate
= usbpn_siocdevprivate
,
276 static void usbpn_setup(struct net_device
*dev
)
278 const u8 addr
= PN_MEDIA_USB
;
281 dev
->netdev_ops
= &usbpn_ops
;
282 dev
->header_ops
= &phonet_header_ops
;
283 dev
->type
= ARPHRD_PHONET
;
284 dev
->flags
= IFF_POINTOPOINT
| IFF_NOARP
;
285 dev
->mtu
= PHONET_MAX_MTU
;
286 dev
->min_mtu
= PHONET_MIN_MTU
;
287 dev
->max_mtu
= PHONET_MAX_MTU
;
288 dev
->hard_header_len
= 1;
290 dev_addr_set(dev
, &addr
);
291 dev
->tx_queue_len
= 3;
293 dev
->needs_free_netdev
= true;
297 * USB driver callbacks
299 static const struct usb_device_id usbpn_ids
[] = {
301 .match_flags
= USB_DEVICE_ID_MATCH_VENDOR
302 | USB_DEVICE_ID_MATCH_INT_CLASS
303 | USB_DEVICE_ID_MATCH_INT_SUBCLASS
,
304 .idVendor
= 0x0421, /* Nokia */
305 .bInterfaceClass
= USB_CLASS_COMM
,
306 .bInterfaceSubClass
= 0xFE,
311 MODULE_DEVICE_TABLE(usb
, usbpn_ids
);
313 static struct usb_driver usbpn_driver
;
315 static int usbpn_probe(struct usb_interface
*intf
, const struct usb_device_id
*id
)
317 static const char ifname
[] = "usbpn%d";
318 const struct usb_cdc_union_desc
*union_header
= NULL
;
319 const struct usb_host_interface
*data_desc
;
320 struct usb_interface
*data_intf
;
321 struct usb_device
*usbdev
= interface_to_usbdev(intf
);
322 struct net_device
*dev
;
323 struct usbpn_dev
*pnd
;
327 struct usb_cdc_parsed_header hdr
;
329 data
= intf
->altsetting
->extra
;
330 len
= intf
->altsetting
->extralen
;
331 cdc_parse_cdc_header(&hdr
, intf
, data
, len
);
332 union_header
= hdr
.usb_cdc_union_desc
;
333 phonet
= hdr
.phonet_magic_present
;
335 if (!union_header
|| !phonet
)
338 data_intf
= usb_ifnum_to_if(usbdev
, union_header
->bSlaveInterface0
);
339 if (data_intf
== NULL
)
341 /* Data interface has one inactive and one active setting */
342 if (data_intf
->num_altsetting
!= 2)
344 if (data_intf
->altsetting
[0].desc
.bNumEndpoints
== 0 &&
345 data_intf
->altsetting
[1].desc
.bNumEndpoints
== 2)
346 data_desc
= data_intf
->altsetting
+ 1;
348 if (data_intf
->altsetting
[0].desc
.bNumEndpoints
== 2 &&
349 data_intf
->altsetting
[1].desc
.bNumEndpoints
== 0)
350 data_desc
= data_intf
->altsetting
;
354 dev
= alloc_netdev(struct_size(pnd
, urbs
, rxq_size
), ifname
,
355 NET_NAME_UNKNOWN
, usbpn_setup
);
359 pnd
= netdev_priv(dev
);
360 SET_NETDEV_DEV(dev
, &intf
->dev
);
365 pnd
->data_intf
= data_intf
;
366 spin_lock_init(&pnd
->tx_lock
);
367 spin_lock_init(&pnd
->rx_lock
);
369 if (usb_pipein(data_desc
->endpoint
[0].desc
.bEndpointAddress
)) {
370 pnd
->rx_pipe
= usb_rcvbulkpipe(usbdev
,
371 data_desc
->endpoint
[0].desc
.bEndpointAddress
);
372 pnd
->tx_pipe
= usb_sndbulkpipe(usbdev
,
373 data_desc
->endpoint
[1].desc
.bEndpointAddress
);
375 pnd
->rx_pipe
= usb_rcvbulkpipe(usbdev
,
376 data_desc
->endpoint
[1].desc
.bEndpointAddress
);
377 pnd
->tx_pipe
= usb_sndbulkpipe(usbdev
,
378 data_desc
->endpoint
[0].desc
.bEndpointAddress
);
380 pnd
->active_setting
= data_desc
- data_intf
->altsetting
;
382 err
= usb_driver_claim_interface(&usbpn_driver
, data_intf
, pnd
);
386 /* Force inactive mode until the network device is brought UP */
387 usb_set_interface(usbdev
, union_header
->bSlaveInterface0
,
388 !pnd
->active_setting
);
389 usb_set_intfdata(intf
, pnd
);
391 err
= register_netdev(dev
);
393 /* Set disconnected flag so that disconnect() returns early. */
394 pnd
->disconnected
= 1;
395 usb_driver_release_interface(&usbpn_driver
, data_intf
);
399 dev_dbg(&dev
->dev
, "USB CDC Phonet device found\n");
403 usb_set_intfdata(intf
, NULL
);
408 static void usbpn_disconnect(struct usb_interface
*intf
)
410 struct usbpn_dev
*pnd
= usb_get_intfdata(intf
);
412 if (pnd
->disconnected
)
415 pnd
->disconnected
= 1;
416 usb_driver_release_interface(&usbpn_driver
,
417 (pnd
->intf
== intf
) ? pnd
->data_intf
: pnd
->intf
);
418 unregister_netdev(pnd
->dev
);
421 static struct usb_driver usbpn_driver
= {
422 .name
= "cdc_phonet",
423 .probe
= usbpn_probe
,
424 .disconnect
= usbpn_disconnect
,
425 .id_table
= usbpn_ids
,
426 .disable_hub_initiated_lpm
= 1,
429 module_usb_driver(usbpn_driver
);
431 MODULE_AUTHOR("Remi Denis-Courmont");
432 MODULE_DESCRIPTION("USB CDC Phonet host interface");
433 MODULE_LICENSE("GPL");