0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/mm.h>
0012 #include <linux/module.h>
0013 #include <linux/gfp.h>
0014 #include <linux/usb.h>
0015 #include <linux/usb/cdc.h>
0016 #include <linux/netdevice.h>
0017 #include <linux/if_arp.h>
0018 #include <linux/if_phonet.h>
0019 #include <linux/phonet.h>
0020
0021 #define PN_MEDIA_USB 0x1B
0022
0023 static const unsigned rxq_size = 17;
0024
0025 struct usbpn_dev {
0026 struct net_device *dev;
0027
0028 struct usb_interface *intf, *data_intf;
0029 struct usb_device *usb;
0030 unsigned int tx_pipe, rx_pipe;
0031 u8 active_setting;
0032 u8 disconnected;
0033
0034 unsigned tx_queue;
0035 spinlock_t tx_lock;
0036
0037 spinlock_t rx_lock;
0038 struct sk_buff *rx_skb;
0039 struct urb *urbs[];
0040 };
0041
0042 static void tx_complete(struct urb *req);
0043 static void rx_complete(struct urb *req);
0044
0045
0046
0047
0048 static netdev_tx_t usbpn_xmit(struct sk_buff *skb, struct net_device *dev)
0049 {
0050 struct usbpn_dev *pnd = netdev_priv(dev);
0051 struct urb *req = NULL;
0052 unsigned long flags;
0053 int err;
0054
0055 if (skb->protocol != htons(ETH_P_PHONET))
0056 goto drop;
0057
0058 req = usb_alloc_urb(0, GFP_ATOMIC);
0059 if (!req)
0060 goto drop;
0061 usb_fill_bulk_urb(req, pnd->usb, pnd->tx_pipe, skb->data, skb->len,
0062 tx_complete, skb);
0063 req->transfer_flags = URB_ZERO_PACKET;
0064 err = usb_submit_urb(req, GFP_ATOMIC);
0065 if (err) {
0066 usb_free_urb(req);
0067 goto drop;
0068 }
0069
0070 spin_lock_irqsave(&pnd->tx_lock, flags);
0071 pnd->tx_queue++;
0072 if (pnd->tx_queue >= dev->tx_queue_len)
0073 netif_stop_queue(dev);
0074 spin_unlock_irqrestore(&pnd->tx_lock, flags);
0075 return NETDEV_TX_OK;
0076
0077 drop:
0078 dev_kfree_skb(skb);
0079 dev->stats.tx_dropped++;
0080 return NETDEV_TX_OK;
0081 }
0082
0083 static void tx_complete(struct urb *req)
0084 {
0085 struct sk_buff *skb = req->context;
0086 struct net_device *dev = skb->dev;
0087 struct usbpn_dev *pnd = netdev_priv(dev);
0088 int status = req->status;
0089 unsigned long flags;
0090
0091 switch (status) {
0092 case 0:
0093 dev->stats.tx_bytes += skb->len;
0094 break;
0095
0096 case -ENOENT:
0097 case -ECONNRESET:
0098 case -ESHUTDOWN:
0099 dev->stats.tx_aborted_errors++;
0100 fallthrough;
0101 default:
0102 dev->stats.tx_errors++;
0103 dev_dbg(&dev->dev, "TX error (%d)\n", status);
0104 }
0105 dev->stats.tx_packets++;
0106
0107 spin_lock_irqsave(&pnd->tx_lock, flags);
0108 pnd->tx_queue--;
0109 netif_wake_queue(dev);
0110 spin_unlock_irqrestore(&pnd->tx_lock, flags);
0111
0112 dev_kfree_skb_any(skb);
0113 usb_free_urb(req);
0114 }
0115
0116 static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags)
0117 {
0118 struct net_device *dev = pnd->dev;
0119 struct page *page;
0120 int err;
0121
0122 page = __dev_alloc_page(gfp_flags | __GFP_NOMEMALLOC);
0123 if (!page)
0124 return -ENOMEM;
0125
0126 usb_fill_bulk_urb(req, pnd->usb, pnd->rx_pipe, page_address(page),
0127 PAGE_SIZE, rx_complete, dev);
0128 req->transfer_flags = 0;
0129 err = usb_submit_urb(req, gfp_flags);
0130 if (unlikely(err)) {
0131 dev_dbg(&dev->dev, "RX submit error (%d)\n", err);
0132 put_page(page);
0133 }
0134 return err;
0135 }
0136
0137 static void rx_complete(struct urb *req)
0138 {
0139 struct net_device *dev = req->context;
0140 struct usbpn_dev *pnd = netdev_priv(dev);
0141 struct page *page = virt_to_page(req->transfer_buffer);
0142 struct sk_buff *skb;
0143 unsigned long flags;
0144 int status = req->status;
0145
0146 switch (status) {
0147 case 0:
0148 spin_lock_irqsave(&pnd->rx_lock, flags);
0149 skb = pnd->rx_skb;
0150 if (!skb) {
0151 skb = pnd->rx_skb = netdev_alloc_skb(dev, 12);
0152 if (likely(skb)) {
0153
0154 skb_put_data(skb, page_address(page), 1);
0155 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
0156 page, 1, req->actual_length,
0157 PAGE_SIZE);
0158 page = NULL;
0159 }
0160 } else {
0161 skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
0162 page, 0, req->actual_length,
0163 PAGE_SIZE);
0164 page = NULL;
0165 }
0166 if (req->actual_length < PAGE_SIZE)
0167 pnd->rx_skb = NULL;
0168 else
0169 skb = NULL;
0170 spin_unlock_irqrestore(&pnd->rx_lock, flags);
0171 if (skb) {
0172 skb->protocol = htons(ETH_P_PHONET);
0173 skb_reset_mac_header(skb);
0174 __skb_pull(skb, 1);
0175 skb->dev = dev;
0176 dev->stats.rx_packets++;
0177 dev->stats.rx_bytes += skb->len;
0178
0179 netif_rx(skb);
0180 }
0181 goto resubmit;
0182
0183 case -ENOENT:
0184 case -ECONNRESET:
0185 case -ESHUTDOWN:
0186 req = NULL;
0187 break;
0188
0189 case -EOVERFLOW:
0190 dev->stats.rx_over_errors++;
0191 dev_dbg(&dev->dev, "RX overflow\n");
0192 break;
0193
0194 case -EILSEQ:
0195 dev->stats.rx_crc_errors++;
0196 break;
0197 }
0198
0199 dev->stats.rx_errors++;
0200 resubmit:
0201 if (page)
0202 put_page(page);
0203 if (req)
0204 rx_submit(pnd, req, GFP_ATOMIC);
0205 }
0206
0207 static int usbpn_close(struct net_device *dev);
0208
0209 static int usbpn_open(struct net_device *dev)
0210 {
0211 struct usbpn_dev *pnd = netdev_priv(dev);
0212 int err;
0213 unsigned i;
0214 unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber;
0215
0216 err = usb_set_interface(pnd->usb, num, pnd->active_setting);
0217 if (err)
0218 return err;
0219
0220 for (i = 0; i < rxq_size; i++) {
0221 struct urb *req = usb_alloc_urb(0, GFP_KERNEL);
0222
0223 if (!req || rx_submit(pnd, req, GFP_KERNEL)) {
0224 usb_free_urb(req);
0225 usbpn_close(dev);
0226 return -ENOMEM;
0227 }
0228 pnd->urbs[i] = req;
0229 }
0230
0231 netif_wake_queue(dev);
0232 return 0;
0233 }
0234
0235 static int usbpn_close(struct net_device *dev)
0236 {
0237 struct usbpn_dev *pnd = netdev_priv(dev);
0238 unsigned i;
0239 unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber;
0240
0241 netif_stop_queue(dev);
0242
0243 for (i = 0; i < rxq_size; i++) {
0244 struct urb *req = pnd->urbs[i];
0245
0246 if (!req)
0247 continue;
0248 usb_kill_urb(req);
0249 usb_free_urb(req);
0250 pnd->urbs[i] = NULL;
0251 }
0252
0253 return usb_set_interface(pnd->usb, num, !pnd->active_setting);
0254 }
0255
0256 static int usbpn_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
0257 void __user *data, int cmd)
0258 {
0259 struct if_phonet_req *req = (struct if_phonet_req *)ifr;
0260
0261 switch (cmd) {
0262 case SIOCPNGAUTOCONF:
0263 req->ifr_phonet_autoconf.device = PN_DEV_PC;
0264 return 0;
0265 }
0266 return -ENOIOCTLCMD;
0267 }
0268
0269 static const struct net_device_ops usbpn_ops = {
0270 .ndo_open = usbpn_open,
0271 .ndo_stop = usbpn_close,
0272 .ndo_start_xmit = usbpn_xmit,
0273 .ndo_siocdevprivate = usbpn_siocdevprivate,
0274 };
0275
0276 static void usbpn_setup(struct net_device *dev)
0277 {
0278 const u8 addr = PN_MEDIA_USB;
0279
0280 dev->features = 0;
0281 dev->netdev_ops = &usbpn_ops;
0282 dev->header_ops = &phonet_header_ops;
0283 dev->type = ARPHRD_PHONET;
0284 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
0285 dev->mtu = PHONET_MAX_MTU;
0286 dev->min_mtu = PHONET_MIN_MTU;
0287 dev->max_mtu = PHONET_MAX_MTU;
0288 dev->hard_header_len = 1;
0289 dev->addr_len = 1;
0290 dev_addr_set(dev, &addr);
0291 dev->tx_queue_len = 3;
0292
0293 dev->needs_free_netdev = true;
0294 }
0295
0296
0297
0298
0299 static const struct usb_device_id usbpn_ids[] = {
0300 {
0301 .match_flags = USB_DEVICE_ID_MATCH_VENDOR
0302 | USB_DEVICE_ID_MATCH_INT_CLASS
0303 | USB_DEVICE_ID_MATCH_INT_SUBCLASS,
0304 .idVendor = 0x0421,
0305 .bInterfaceClass = USB_CLASS_COMM,
0306 .bInterfaceSubClass = 0xFE,
0307 },
0308 { },
0309 };
0310
0311 MODULE_DEVICE_TABLE(usb, usbpn_ids);
0312
0313 static struct usb_driver usbpn_driver;
0314
0315 static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)
0316 {
0317 static const char ifname[] = "usbpn%d";
0318 const struct usb_cdc_union_desc *union_header = NULL;
0319 const struct usb_host_interface *data_desc;
0320 struct usb_interface *data_intf;
0321 struct usb_device *usbdev = interface_to_usbdev(intf);
0322 struct net_device *dev;
0323 struct usbpn_dev *pnd;
0324 u8 *data;
0325 int phonet = 0;
0326 int len, err;
0327 struct usb_cdc_parsed_header hdr;
0328
0329 data = intf->altsetting->extra;
0330 len = intf->altsetting->extralen;
0331 cdc_parse_cdc_header(&hdr, intf, data, len);
0332 union_header = hdr.usb_cdc_union_desc;
0333 phonet = hdr.phonet_magic_present;
0334
0335 if (!union_header || !phonet)
0336 return -EINVAL;
0337
0338 data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0);
0339 if (data_intf == NULL)
0340 return -ENODEV;
0341
0342 if (data_intf->num_altsetting != 2)
0343 return -EINVAL;
0344 if (data_intf->altsetting[0].desc.bNumEndpoints == 0 &&
0345 data_intf->altsetting[1].desc.bNumEndpoints == 2)
0346 data_desc = data_intf->altsetting + 1;
0347 else
0348 if (data_intf->altsetting[0].desc.bNumEndpoints == 2 &&
0349 data_intf->altsetting[1].desc.bNumEndpoints == 0)
0350 data_desc = data_intf->altsetting;
0351 else
0352 return -EINVAL;
0353
0354 dev = alloc_netdev(struct_size(pnd, urbs, rxq_size), ifname,
0355 NET_NAME_UNKNOWN, usbpn_setup);
0356 if (!dev)
0357 return -ENOMEM;
0358
0359 pnd = netdev_priv(dev);
0360 SET_NETDEV_DEV(dev, &intf->dev);
0361
0362 pnd->dev = dev;
0363 pnd->usb = usbdev;
0364 pnd->intf = intf;
0365 pnd->data_intf = data_intf;
0366 spin_lock_init(&pnd->tx_lock);
0367 spin_lock_init(&pnd->rx_lock);
0368
0369 if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) {
0370 pnd->rx_pipe = usb_rcvbulkpipe(usbdev,
0371 data_desc->endpoint[0].desc.bEndpointAddress);
0372 pnd->tx_pipe = usb_sndbulkpipe(usbdev,
0373 data_desc->endpoint[1].desc.bEndpointAddress);
0374 } else {
0375 pnd->rx_pipe = usb_rcvbulkpipe(usbdev,
0376 data_desc->endpoint[1].desc.bEndpointAddress);
0377 pnd->tx_pipe = usb_sndbulkpipe(usbdev,
0378 data_desc->endpoint[0].desc.bEndpointAddress);
0379 }
0380 pnd->active_setting = data_desc - data_intf->altsetting;
0381
0382 err = usb_driver_claim_interface(&usbpn_driver, data_intf, pnd);
0383 if (err)
0384 goto out;
0385
0386
0387 usb_set_interface(usbdev, union_header->bSlaveInterface0,
0388 !pnd->active_setting);
0389 usb_set_intfdata(intf, pnd);
0390
0391 err = register_netdev(dev);
0392 if (err) {
0393
0394 pnd->disconnected = 1;
0395 usb_driver_release_interface(&usbpn_driver, data_intf);
0396 goto out;
0397 }
0398
0399 dev_dbg(&dev->dev, "USB CDC Phonet device found\n");
0400 return 0;
0401
0402 out:
0403 usb_set_intfdata(intf, NULL);
0404 free_netdev(dev);
0405 return err;
0406 }
0407
0408 static void usbpn_disconnect(struct usb_interface *intf)
0409 {
0410 struct usbpn_dev *pnd = usb_get_intfdata(intf);
0411
0412 if (pnd->disconnected)
0413 return;
0414
0415 pnd->disconnected = 1;
0416 usb_driver_release_interface(&usbpn_driver,
0417 (pnd->intf == intf) ? pnd->data_intf : pnd->intf);
0418 unregister_netdev(pnd->dev);
0419 }
0420
0421 static struct usb_driver usbpn_driver = {
0422 .name = "cdc_phonet",
0423 .probe = usbpn_probe,
0424 .disconnect = usbpn_disconnect,
0425 .id_table = usbpn_ids,
0426 .disable_hub_initiated_lpm = 1,
0427 };
0428
0429 module_usb_driver(usbpn_driver);
0430
0431 MODULE_AUTHOR("Remi Denis-Courmont");
0432 MODULE_DESCRIPTION("USB CDC Phonet host interface");
0433 MODULE_LICENSE("GPL");