Lines Matching +full:rx +full:- +full:inactive
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
55 if (skb->protocol != htons(ETH_P_PHONET)) in usbpn_xmit()
61 usb_fill_bulk_urb(req, pnd->usb, pnd->tx_pipe, skb->data, skb->len, in usbpn_xmit()
63 req->transfer_flags = URB_ZERO_PACKET; in usbpn_xmit()
70 spin_lock_irqsave(&pnd->tx_lock, flags); in usbpn_xmit()
71 pnd->tx_queue++; in usbpn_xmit()
72 if (pnd->tx_queue >= dev->tx_queue_len) in usbpn_xmit()
74 spin_unlock_irqrestore(&pnd->tx_lock, flags); in usbpn_xmit()
79 dev->stats.tx_dropped++; in usbpn_xmit()
85 struct sk_buff *skb = req->context; in tx_complete()
86 struct net_device *dev = skb->dev; in tx_complete()
88 int status = req->status; in tx_complete()
93 dev->stats.tx_bytes += skb->len; in tx_complete()
96 case -ENOENT: in tx_complete()
97 case -ECONNRESET: in tx_complete()
98 case -ESHUTDOWN: in tx_complete()
99 dev->stats.tx_aborted_errors++; in tx_complete()
102 dev->stats.tx_errors++; in tx_complete()
103 dev_dbg(&dev->dev, "TX error (%d)\n", status); in tx_complete()
105 dev->stats.tx_packets++; in tx_complete()
107 spin_lock_irqsave(&pnd->tx_lock, flags); in tx_complete()
108 pnd->tx_queue--; in tx_complete()
110 spin_unlock_irqrestore(&pnd->tx_lock, flags); in tx_complete()
118 struct net_device *dev = pnd->dev; in rx_submit()
124 return -ENOMEM; in rx_submit()
126 usb_fill_bulk_urb(req, pnd->usb, pnd->rx_pipe, page_address(page), in rx_submit()
128 req->transfer_flags = 0; in rx_submit()
131 dev_dbg(&dev->dev, "RX submit error (%d)\n", err); in rx_submit()
139 struct net_device *dev = req->context; in rx_complete()
141 struct page *page = virt_to_page(req->transfer_buffer); in rx_complete()
144 int status = req->status; in rx_complete()
148 spin_lock_irqsave(&pnd->rx_lock, flags); in rx_complete()
149 skb = pnd->rx_skb; in rx_complete()
151 skb = pnd->rx_skb = netdev_alloc_skb(dev, 12); in rx_complete()
155 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, in rx_complete()
156 page, 1, req->actual_length, in rx_complete()
161 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, in rx_complete()
162 page, 0, req->actual_length, in rx_complete()
166 if (req->actual_length < PAGE_SIZE) in rx_complete()
167 pnd->rx_skb = NULL; /* Last fragment */ in rx_complete()
170 spin_unlock_irqrestore(&pnd->rx_lock, flags); in rx_complete()
172 skb->protocol = htons(ETH_P_PHONET); in rx_complete()
175 skb->dev = dev; in rx_complete()
176 dev->stats.rx_packets++; in rx_complete()
177 dev->stats.rx_bytes += skb->len; in rx_complete()
183 case -ENOENT: in rx_complete()
184 case -ECONNRESET: in rx_complete()
185 case -ESHUTDOWN: in rx_complete()
189 case -EOVERFLOW: in rx_complete()
190 dev->stats.rx_over_errors++; in rx_complete()
191 dev_dbg(&dev->dev, "RX overflow\n"); in rx_complete()
194 case -EILSEQ: in rx_complete()
195 dev->stats.rx_crc_errors++; in rx_complete()
199 dev->stats.rx_errors++; in rx_complete()
214 unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; in usbpn_open()
216 err = usb_set_interface(pnd->usb, num, pnd->active_setting); in usbpn_open()
226 return -ENOMEM; in usbpn_open()
228 pnd->urbs[i] = req; in usbpn_open()
239 unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; in usbpn_close()
244 struct urb *req = pnd->urbs[i]; in usbpn_close()
250 pnd->urbs[i] = NULL; in usbpn_close()
253 return usb_set_interface(pnd->usb, num, !pnd->active_setting); in usbpn_close()
263 req->ifr_phonet_autoconf.device = PN_DEV_PC; in usbpn_siocdevprivate()
266 return -ENOIOCTLCMD; in usbpn_siocdevprivate()
280 dev->features = 0; in usbpn_setup()
281 dev->netdev_ops = &usbpn_ops; in usbpn_setup()
282 dev->header_ops = &phonet_header_ops; in usbpn_setup()
283 dev->type = ARPHRD_PHONET; in usbpn_setup()
284 dev->flags = IFF_POINTOPOINT | IFF_NOARP; in usbpn_setup()
285 dev->mtu = PHONET_MAX_MTU; in usbpn_setup()
286 dev->min_mtu = PHONET_MIN_MTU; in usbpn_setup()
287 dev->max_mtu = PHONET_MAX_MTU; in usbpn_setup()
288 dev->hard_header_len = 1; in usbpn_setup()
289 dev->addr_len = 1; in usbpn_setup()
291 dev->tx_queue_len = 3; in usbpn_setup()
293 dev->needs_free_netdev = true; in usbpn_setup()
329 data = intf->altsetting->extra; in usbpn_probe()
330 len = intf->altsetting->extralen; in usbpn_probe()
336 return -EINVAL; in usbpn_probe()
338 data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0); in usbpn_probe()
340 return -ENODEV; in usbpn_probe()
341 /* Data interface has one inactive and one active setting */ in usbpn_probe()
342 if (data_intf->num_altsetting != 2) in usbpn_probe()
343 return -EINVAL; in usbpn_probe()
344 if (data_intf->altsetting[0].desc.bNumEndpoints == 0 && in usbpn_probe()
345 data_intf->altsetting[1].desc.bNumEndpoints == 2) in usbpn_probe()
346 data_desc = data_intf->altsetting + 1; in usbpn_probe()
348 if (data_intf->altsetting[0].desc.bNumEndpoints == 2 && in usbpn_probe()
349 data_intf->altsetting[1].desc.bNumEndpoints == 0) in usbpn_probe()
350 data_desc = data_intf->altsetting; in usbpn_probe()
352 return -EINVAL; in usbpn_probe()
357 return -ENOMEM; in usbpn_probe()
360 SET_NETDEV_DEV(dev, &intf->dev); in usbpn_probe()
362 pnd->dev = dev; in usbpn_probe()
363 pnd->usb = usbdev; in usbpn_probe()
364 pnd->intf = intf; in usbpn_probe()
365 pnd->data_intf = data_intf; in usbpn_probe()
366 spin_lock_init(&pnd->tx_lock); in usbpn_probe()
367 spin_lock_init(&pnd->rx_lock); in usbpn_probe()
369 if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { in usbpn_probe()
370 pnd->rx_pipe = usb_rcvbulkpipe(usbdev, in usbpn_probe()
371 data_desc->endpoint[0].desc.bEndpointAddress); in usbpn_probe()
372 pnd->tx_pipe = usb_sndbulkpipe(usbdev, in usbpn_probe()
373 data_desc->endpoint[1].desc.bEndpointAddress); in usbpn_probe()
375 pnd->rx_pipe = usb_rcvbulkpipe(usbdev, in usbpn_probe()
376 data_desc->endpoint[1].desc.bEndpointAddress); in usbpn_probe()
377 pnd->tx_pipe = usb_sndbulkpipe(usbdev, in usbpn_probe()
378 data_desc->endpoint[0].desc.bEndpointAddress); in usbpn_probe()
380 pnd->active_setting = data_desc - data_intf->altsetting; in usbpn_probe()
386 /* Force inactive mode until the network device is brought UP */ in usbpn_probe()
387 usb_set_interface(usbdev, union_header->bSlaveInterface0, in usbpn_probe()
388 !pnd->active_setting); in usbpn_probe()
394 pnd->disconnected = 1; in usbpn_probe()
399 dev_dbg(&dev->dev, "USB CDC Phonet device found\n"); in usbpn_probe()
412 if (pnd->disconnected) in usbpn_disconnect()
415 pnd->disconnected = 1; in usbpn_disconnect()
417 (pnd->intf == intf) ? pnd->data_intf : pnd->intf); in usbpn_disconnect()
418 unregister_netdev(pnd->dev); in usbpn_disconnect()
431 MODULE_AUTHOR("Remi Denis-Courmont");