0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 #include <linux/kernel.h>
0047 #include <linux/errno.h>
0048 #include <linux/slab.h>
0049 #include <linux/module.h>
0050 #include <linux/netdevice.h>
0051 #include <linux/etherdevice.h>
0052 #include <linux/ethtool.h>
0053 #include <linux/usb.h>
0054 #include <linux/workqueue.h>
0055
0056 #define USB_VENDOR_APPLE 0x05ac
0057
0058 #define IPHETH_USBINTF_CLASS 255
0059 #define IPHETH_USBINTF_SUBCLASS 253
0060 #define IPHETH_USBINTF_PROTO 1
0061
0062 #define IPHETH_BUF_SIZE 1514
0063 #define IPHETH_IP_ALIGN 2
0064 #define IPHETH_TX_TIMEOUT (5 * HZ)
0065
0066 #define IPHETH_INTFNUM 2
0067 #define IPHETH_ALT_INTFNUM 1
0068
0069 #define IPHETH_CTRL_ENDP 0x00
0070 #define IPHETH_CTRL_BUF_SIZE 0x40
0071 #define IPHETH_CTRL_TIMEOUT (5 * HZ)
0072
0073 #define IPHETH_CMD_GET_MACADDR 0x00
0074 #define IPHETH_CMD_CARRIER_CHECK 0x45
0075
0076 #define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
0077 #define IPHETH_CARRIER_ON 0x04
0078
0079 static const struct usb_device_id ipheth_table[] = {
0080 { USB_VENDOR_AND_INTERFACE_INFO(USB_VENDOR_APPLE, IPHETH_USBINTF_CLASS,
0081 IPHETH_USBINTF_SUBCLASS,
0082 IPHETH_USBINTF_PROTO) },
0083 { }
0084 };
0085 MODULE_DEVICE_TABLE(usb, ipheth_table);
0086
0087 struct ipheth_device {
0088 struct usb_device *udev;
0089 struct usb_interface *intf;
0090 struct net_device *net;
0091 struct urb *tx_urb;
0092 struct urb *rx_urb;
0093 unsigned char *tx_buf;
0094 unsigned char *rx_buf;
0095 unsigned char *ctrl_buf;
0096 u8 bulk_in;
0097 u8 bulk_out;
0098 struct delayed_work carrier_work;
0099 bool confirmed_pairing;
0100 };
0101
0102 static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
0103
0104 static int ipheth_alloc_urbs(struct ipheth_device *iphone)
0105 {
0106 struct urb *tx_urb = NULL;
0107 struct urb *rx_urb = NULL;
0108 u8 *tx_buf = NULL;
0109 u8 *rx_buf = NULL;
0110
0111 tx_urb = usb_alloc_urb(0, GFP_KERNEL);
0112 if (tx_urb == NULL)
0113 goto error_nomem;
0114
0115 rx_urb = usb_alloc_urb(0, GFP_KERNEL);
0116 if (rx_urb == NULL)
0117 goto free_tx_urb;
0118
0119 tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE,
0120 GFP_KERNEL, &tx_urb->transfer_dma);
0121 if (tx_buf == NULL)
0122 goto free_rx_urb;
0123
0124 rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
0125 GFP_KERNEL, &rx_urb->transfer_dma);
0126 if (rx_buf == NULL)
0127 goto free_tx_buf;
0128
0129
0130 iphone->tx_urb = tx_urb;
0131 iphone->rx_urb = rx_urb;
0132 iphone->tx_buf = tx_buf;
0133 iphone->rx_buf = rx_buf;
0134 return 0;
0135
0136 free_tx_buf:
0137 usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
0138 tx_urb->transfer_dma);
0139 free_rx_urb:
0140 usb_free_urb(rx_urb);
0141 free_tx_urb:
0142 usb_free_urb(tx_urb);
0143 error_nomem:
0144 return -ENOMEM;
0145 }
0146
0147 static void ipheth_free_urbs(struct ipheth_device *iphone)
0148 {
0149 usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf,
0150 iphone->rx_urb->transfer_dma);
0151 usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
0152 iphone->tx_urb->transfer_dma);
0153 usb_free_urb(iphone->rx_urb);
0154 usb_free_urb(iphone->tx_urb);
0155 }
0156
0157 static void ipheth_kill_urbs(struct ipheth_device *dev)
0158 {
0159 usb_kill_urb(dev->tx_urb);
0160 usb_kill_urb(dev->rx_urb);
0161 }
0162
0163 static void ipheth_rcvbulk_callback(struct urb *urb)
0164 {
0165 struct ipheth_device *dev;
0166 struct sk_buff *skb;
0167 int status;
0168 char *buf;
0169 int len;
0170
0171 dev = urb->context;
0172 if (dev == NULL)
0173 return;
0174
0175 status = urb->status;
0176 switch (status) {
0177 case -ENOENT:
0178 case -ECONNRESET:
0179 case -ESHUTDOWN:
0180 case -EPROTO:
0181 return;
0182 case 0:
0183 break;
0184 default:
0185 dev_err(&dev->intf->dev, "%s: urb status: %d\n",
0186 __func__, status);
0187 return;
0188 }
0189
0190 if (urb->actual_length <= IPHETH_IP_ALIGN) {
0191 dev->net->stats.rx_length_errors++;
0192 return;
0193 }
0194 len = urb->actual_length - IPHETH_IP_ALIGN;
0195 buf = urb->transfer_buffer + IPHETH_IP_ALIGN;
0196
0197 skb = dev_alloc_skb(len);
0198 if (!skb) {
0199 dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n",
0200 __func__);
0201 dev->net->stats.rx_dropped++;
0202 return;
0203 }
0204
0205 skb_put_data(skb, buf, len);
0206 skb->dev = dev->net;
0207 skb->protocol = eth_type_trans(skb, dev->net);
0208
0209 dev->net->stats.rx_packets++;
0210 dev->net->stats.rx_bytes += len;
0211 dev->confirmed_pairing = true;
0212 netif_rx(skb);
0213 ipheth_rx_submit(dev, GFP_ATOMIC);
0214 }
0215
0216 static void ipheth_sndbulk_callback(struct urb *urb)
0217 {
0218 struct ipheth_device *dev;
0219 int status = urb->status;
0220
0221 dev = urb->context;
0222 if (dev == NULL)
0223 return;
0224
0225 if (status != 0 &&
0226 status != -ENOENT &&
0227 status != -ECONNRESET &&
0228 status != -ESHUTDOWN)
0229 dev_err(&dev->intf->dev, "%s: urb status: %d\n",
0230 __func__, status);
0231
0232 if (status == 0)
0233 netif_wake_queue(dev->net);
0234 else
0235
0236 schedule_delayed_work(&dev->carrier_work, 0);
0237 }
0238
0239 static int ipheth_carrier_set(struct ipheth_device *dev)
0240 {
0241 struct usb_device *udev;
0242 int retval;
0243
0244 if (!dev->confirmed_pairing)
0245 return 0;
0246
0247 udev = dev->udev;
0248 retval = usb_control_msg(udev,
0249 usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
0250 IPHETH_CMD_CARRIER_CHECK,
0251 0xc0,
0252 0x00,
0253 0x02,
0254 dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE,
0255 IPHETH_CTRL_TIMEOUT);
0256 if (retval < 0) {
0257 dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n",
0258 __func__, retval);
0259 return retval;
0260 }
0261
0262 if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON) {
0263 netif_carrier_on(dev->net);
0264 if (dev->tx_urb->status != -EINPROGRESS)
0265 netif_wake_queue(dev->net);
0266 } else {
0267 netif_carrier_off(dev->net);
0268 netif_stop_queue(dev->net);
0269 }
0270 return 0;
0271 }
0272
0273 static void ipheth_carrier_check_work(struct work_struct *work)
0274 {
0275 struct ipheth_device *dev = container_of(work, struct ipheth_device,
0276 carrier_work.work);
0277
0278 ipheth_carrier_set(dev);
0279 schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
0280 }
0281
0282 static int ipheth_get_macaddr(struct ipheth_device *dev)
0283 {
0284 struct usb_device *udev = dev->udev;
0285 struct net_device *net = dev->net;
0286 int retval;
0287
0288 retval = usb_control_msg(udev,
0289 usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
0290 IPHETH_CMD_GET_MACADDR,
0291 0xc0,
0292 0x00,
0293 0x02,
0294 dev->ctrl_buf,
0295 IPHETH_CTRL_BUF_SIZE,
0296 IPHETH_CTRL_TIMEOUT);
0297 if (retval < 0) {
0298 dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n",
0299 __func__, retval);
0300 } else if (retval < ETH_ALEN) {
0301 dev_err(&dev->intf->dev,
0302 "%s: usb_control_msg: short packet: %d bytes\n",
0303 __func__, retval);
0304 retval = -EINVAL;
0305 } else {
0306 eth_hw_addr_set(net, dev->ctrl_buf);
0307 retval = 0;
0308 }
0309
0310 return retval;
0311 }
0312
0313 static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
0314 {
0315 struct usb_device *udev = dev->udev;
0316 int retval;
0317
0318 usb_fill_bulk_urb(dev->rx_urb, udev,
0319 usb_rcvbulkpipe(udev, dev->bulk_in),
0320 dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
0321 ipheth_rcvbulk_callback,
0322 dev);
0323 dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0324
0325 retval = usb_submit_urb(dev->rx_urb, mem_flags);
0326 if (retval)
0327 dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n",
0328 __func__, retval);
0329 return retval;
0330 }
0331
0332 static int ipheth_open(struct net_device *net)
0333 {
0334 struct ipheth_device *dev = netdev_priv(net);
0335 struct usb_device *udev = dev->udev;
0336 int retval = 0;
0337
0338 usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM);
0339
0340 retval = ipheth_carrier_set(dev);
0341 if (retval)
0342 return retval;
0343
0344 retval = ipheth_rx_submit(dev, GFP_KERNEL);
0345 if (retval)
0346 return retval;
0347
0348 schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
0349 return retval;
0350 }
0351
0352 static int ipheth_close(struct net_device *net)
0353 {
0354 struct ipheth_device *dev = netdev_priv(net);
0355
0356 cancel_delayed_work_sync(&dev->carrier_work);
0357 netif_stop_queue(net);
0358 return 0;
0359 }
0360
0361 static netdev_tx_t ipheth_tx(struct sk_buff *skb, struct net_device *net)
0362 {
0363 struct ipheth_device *dev = netdev_priv(net);
0364 struct usb_device *udev = dev->udev;
0365 int retval;
0366
0367
0368 if (skb->len > IPHETH_BUF_SIZE) {
0369 WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
0370 dev->net->stats.tx_dropped++;
0371 dev_kfree_skb_any(skb);
0372 return NETDEV_TX_OK;
0373 }
0374
0375 memcpy(dev->tx_buf, skb->data, skb->len);
0376 if (skb->len < IPHETH_BUF_SIZE)
0377 memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len);
0378
0379 usb_fill_bulk_urb(dev->tx_urb, udev,
0380 usb_sndbulkpipe(udev, dev->bulk_out),
0381 dev->tx_buf, IPHETH_BUF_SIZE,
0382 ipheth_sndbulk_callback,
0383 dev);
0384 dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0385
0386 netif_stop_queue(net);
0387 retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);
0388 if (retval) {
0389 dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n",
0390 __func__, retval);
0391 dev->net->stats.tx_errors++;
0392 dev_kfree_skb_any(skb);
0393 netif_wake_queue(net);
0394 } else {
0395 dev->net->stats.tx_packets++;
0396 dev->net->stats.tx_bytes += skb->len;
0397 dev_consume_skb_any(skb);
0398 }
0399
0400 return NETDEV_TX_OK;
0401 }
0402
0403 static void ipheth_tx_timeout(struct net_device *net, unsigned int txqueue)
0404 {
0405 struct ipheth_device *dev = netdev_priv(net);
0406
0407 dev_err(&dev->intf->dev, "%s: TX timeout\n", __func__);
0408 dev->net->stats.tx_errors++;
0409 usb_unlink_urb(dev->tx_urb);
0410 }
0411
0412 static u32 ipheth_ethtool_op_get_link(struct net_device *net)
0413 {
0414 struct ipheth_device *dev = netdev_priv(net);
0415 return netif_carrier_ok(dev->net);
0416 }
0417
0418 static const struct ethtool_ops ops = {
0419 .get_link = ipheth_ethtool_op_get_link
0420 };
0421
0422 static const struct net_device_ops ipheth_netdev_ops = {
0423 .ndo_open = ipheth_open,
0424 .ndo_stop = ipheth_close,
0425 .ndo_start_xmit = ipheth_tx,
0426 .ndo_tx_timeout = ipheth_tx_timeout,
0427 };
0428
0429 static int ipheth_probe(struct usb_interface *intf,
0430 const struct usb_device_id *id)
0431 {
0432 struct usb_device *udev = interface_to_usbdev(intf);
0433 struct usb_host_interface *hintf;
0434 struct usb_endpoint_descriptor *endp;
0435 struct ipheth_device *dev;
0436 struct net_device *netdev;
0437 int i;
0438 int retval;
0439
0440 netdev = alloc_etherdev(sizeof(struct ipheth_device));
0441 if (!netdev)
0442 return -ENOMEM;
0443
0444 netdev->netdev_ops = &ipheth_netdev_ops;
0445 netdev->watchdog_timeo = IPHETH_TX_TIMEOUT;
0446 strscpy(netdev->name, "eth%d", sizeof(netdev->name));
0447
0448 dev = netdev_priv(netdev);
0449 dev->udev = udev;
0450 dev->net = netdev;
0451 dev->intf = intf;
0452 dev->confirmed_pairing = false;
0453
0454 hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
0455 if (hintf == NULL) {
0456 retval = -ENODEV;
0457 dev_err(&intf->dev, "Unable to find alternate settings interface\n");
0458 goto err_endpoints;
0459 }
0460
0461 for (i = 0; i < hintf->desc.bNumEndpoints; i++) {
0462 endp = &hintf->endpoint[i].desc;
0463 if (usb_endpoint_is_bulk_in(endp))
0464 dev->bulk_in = endp->bEndpointAddress;
0465 else if (usb_endpoint_is_bulk_out(endp))
0466 dev->bulk_out = endp->bEndpointAddress;
0467 }
0468 if (!(dev->bulk_in && dev->bulk_out)) {
0469 retval = -ENODEV;
0470 dev_err(&intf->dev, "Unable to find endpoints\n");
0471 goto err_endpoints;
0472 }
0473
0474 dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL);
0475 if (dev->ctrl_buf == NULL) {
0476 retval = -ENOMEM;
0477 goto err_alloc_ctrl_buf;
0478 }
0479
0480 retval = ipheth_get_macaddr(dev);
0481 if (retval)
0482 goto err_get_macaddr;
0483
0484 INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work);
0485
0486 retval = ipheth_alloc_urbs(dev);
0487 if (retval) {
0488 dev_err(&intf->dev, "error allocating urbs: %d\n", retval);
0489 goto err_alloc_urbs;
0490 }
0491
0492 usb_set_intfdata(intf, dev);
0493
0494 SET_NETDEV_DEV(netdev, &intf->dev);
0495 netdev->ethtool_ops = &ops;
0496
0497 retval = register_netdev(netdev);
0498 if (retval) {
0499 dev_err(&intf->dev, "error registering netdev: %d\n", retval);
0500 retval = -EIO;
0501 goto err_register_netdev;
0502 }
0503
0504 netif_carrier_off(netdev);
0505 netif_tx_stop_all_queues(netdev);
0506 dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n");
0507 return 0;
0508
0509 err_register_netdev:
0510 ipheth_free_urbs(dev);
0511 err_alloc_urbs:
0512 err_get_macaddr:
0513 err_alloc_ctrl_buf:
0514 kfree(dev->ctrl_buf);
0515 err_endpoints:
0516 free_netdev(netdev);
0517 return retval;
0518 }
0519
0520 static void ipheth_disconnect(struct usb_interface *intf)
0521 {
0522 struct ipheth_device *dev;
0523
0524 dev = usb_get_intfdata(intf);
0525 if (dev != NULL) {
0526 unregister_netdev(dev->net);
0527 ipheth_kill_urbs(dev);
0528 ipheth_free_urbs(dev);
0529 kfree(dev->ctrl_buf);
0530 free_netdev(dev->net);
0531 }
0532 usb_set_intfdata(intf, NULL);
0533 dev_info(&intf->dev, "Apple iPhone USB Ethernet now disconnected\n");
0534 }
0535
0536 static struct usb_driver ipheth_driver = {
0537 .name = "ipheth",
0538 .probe = ipheth_probe,
0539 .disconnect = ipheth_disconnect,
0540 .id_table = ipheth_table,
0541 .disable_hub_initiated_lpm = 1,
0542 };
0543
0544 module_usb_driver(ipheth_driver);
0545
0546 MODULE_AUTHOR("Diego Giagio <diego@giagio.com>");
0547 MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver");
0548 MODULE_LICENSE("Dual BSD/GPL");