Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
2e15fadb5e
@ -543,7 +543,7 @@
|
||||
+serverip=192.168.1.254
|
||||
+loadaddr=0x46000000
|
||||
+console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0
|
||||
+bootargs=root=/dev/mmcblk0p65
|
||||
+bootargs=root=/dev/mmcblk0p65 rootwait
|
||||
+bootcmd=if pstore check ; then run boot_recovery ; else run boot_emmc ; fi
|
||||
+bootconf=config-1
|
||||
+bootdelay=0
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 2203718c2f59ffdd6c78d54e5add594aebb4461e Mon Sep 17 00:00:00 2001
|
||||
From: Georgi Valkov <gvalkov@gmail.com>
|
||||
Date: Wed, 7 Jun 2023 15:56:59 +0200
|
||||
Subject: [PATCH 1/4] usbnet: ipheth: fix risk of NULL pointer deallocation
|
||||
|
||||
The cleanup precedure in ipheth_probe will attempt to free a
|
||||
NULL pointer in dev->ctrl_buf if the memory allocation for
|
||||
this buffer is not successful. While kfree ignores NULL pointers,
|
||||
and the existing code is safe, it is a better design to rearrange
|
||||
the goto labels and avoid this.
|
||||
|
||||
Signed-off-by: Georgi Valkov <gvalkov@gmail.com>
|
||||
Signed-off-by: Foster Snowhill <forst@pen.gy>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/usb/ipheth.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/usb/ipheth.c
|
||||
+++ b/drivers/net/usb/ipheth.c
|
||||
@@ -510,8 +510,8 @@ err_register_netdev:
|
||||
ipheth_free_urbs(dev);
|
||||
err_alloc_urbs:
|
||||
err_get_macaddr:
|
||||
-err_alloc_ctrl_buf:
|
||||
kfree(dev->ctrl_buf);
|
||||
+err_alloc_ctrl_buf:
|
||||
err_endpoints:
|
||||
free_netdev(netdev);
|
||||
return retval;
|
@ -0,0 +1,35 @@
|
||||
From 3e65efcca87a9bb5f3b864e0a43d167bc0a8688c Mon Sep 17 00:00:00 2001
|
||||
From: Foster Snowhill <forst@pen.gy>
|
||||
Date: Wed, 7 Jun 2023 15:57:00 +0200
|
||||
Subject: [PATCH 2/4] usbnet: ipheth: transmit URBs without trailing padding
|
||||
|
||||
The behaviour of the official iOS tethering driver on macOS is to not
|
||||
transmit any trailing padding at the end of URBs. This is applicable
|
||||
to both NCM and legacy modes, including older devices.
|
||||
|
||||
Adapt the driver to not include trailing padding in TX URBs, matching
|
||||
the behaviour of the official macOS driver.
|
||||
|
||||
Signed-off-by: Foster Snowhill <forst@pen.gy>
|
||||
Tested-by: Georgi Valkov <gvalkov@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/usb/ipheth.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/usb/ipheth.c
|
||||
+++ b/drivers/net/usb/ipheth.c
|
||||
@@ -373,12 +373,10 @@ static netdev_tx_t ipheth_tx(struct sk_b
|
||||
}
|
||||
|
||||
memcpy(dev->tx_buf, skb->data, skb->len);
|
||||
- if (skb->len < IPHETH_BUF_SIZE)
|
||||
- memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len);
|
||||
|
||||
usb_fill_bulk_urb(dev->tx_urb, udev,
|
||||
usb_sndbulkpipe(udev, dev->bulk_out),
|
||||
- dev->tx_buf, IPHETH_BUF_SIZE,
|
||||
+ dev->tx_buf, skb->len,
|
||||
ipheth_sndbulk_callback,
|
||||
dev);
|
||||
dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
@ -0,0 +1,326 @@
|
||||
From a2d274c62e44b1995c170595db3865c6fe701226 Mon Sep 17 00:00:00 2001
|
||||
From: Foster Snowhill <forst@pen.gy>
|
||||
Date: Wed, 7 Jun 2023 15:57:01 +0200
|
||||
Subject: [PATCH 3/4] usbnet: ipheth: add CDC NCM support
|
||||
|
||||
Recent iOS releases support CDC NCM encapsulation on RX. This mode is
|
||||
the default on macOS and Windows. In this mode, an iOS device may include
|
||||
one or more Ethernet frames inside a single URB.
|
||||
|
||||
Freshly booted iOS devices start in legacy mode, but are put into
|
||||
NCM mode by the official Apple driver. When reconnecting such a device
|
||||
from a macOS/Windows machine to a Linux host, the device stays in
|
||||
NCM mode, making it unusable with the legacy ipheth driver code.
|
||||
|
||||
To correctly support such a device, the driver has to either support
|
||||
the NCM mode too, or put the device back into legacy mode.
|
||||
|
||||
To match the behaviour of the macOS/Windows driver, and since there
|
||||
is no documented control command to revert to legacy mode, implement
|
||||
NCM support. The device is attempted to be put into NCM mode by default,
|
||||
and falls back to legacy mode if the attempt fails.
|
||||
|
||||
Signed-off-by: Foster Snowhill <forst@pen.gy>
|
||||
Tested-by: Georgi Valkov <gvalkov@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/usb/ipheth.c | 180 +++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 155 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/net/usb/ipheth.c
|
||||
+++ b/drivers/net/usb/ipheth.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/workqueue.h>
|
||||
+#include <linux/usb/cdc.h>
|
||||
|
||||
#define USB_VENDOR_APPLE 0x05ac
|
||||
|
||||
@@ -59,8 +60,12 @@
|
||||
#define IPHETH_USBINTF_SUBCLASS 253
|
||||
#define IPHETH_USBINTF_PROTO 1
|
||||
|
||||
-#define IPHETH_BUF_SIZE 1514
|
||||
#define IPHETH_IP_ALIGN 2 /* padding at front of URB */
|
||||
+#define IPHETH_NCM_HEADER_SIZE (12 + 96) /* NCMH + NCM0 */
|
||||
+#define IPHETH_TX_BUF_SIZE ETH_FRAME_LEN
|
||||
+#define IPHETH_RX_BUF_SIZE_LEGACY (IPHETH_IP_ALIGN + ETH_FRAME_LEN)
|
||||
+#define IPHETH_RX_BUF_SIZE_NCM 65536
|
||||
+
|
||||
#define IPHETH_TX_TIMEOUT (5 * HZ)
|
||||
|
||||
#define IPHETH_INTFNUM 2
|
||||
@@ -71,6 +76,7 @@
|
||||
#define IPHETH_CTRL_TIMEOUT (5 * HZ)
|
||||
|
||||
#define IPHETH_CMD_GET_MACADDR 0x00
|
||||
+#define IPHETH_CMD_ENABLE_NCM 0x04
|
||||
#define IPHETH_CMD_CARRIER_CHECK 0x45
|
||||
|
||||
#define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
|
||||
@@ -97,6 +103,8 @@ struct ipheth_device {
|
||||
u8 bulk_out;
|
||||
struct delayed_work carrier_work;
|
||||
bool confirmed_pairing;
|
||||
+ int (*rcvbulk_callback)(struct urb *urb);
|
||||
+ size_t rx_buf_len;
|
||||
};
|
||||
|
||||
static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
|
||||
@@ -116,12 +124,12 @@ static int ipheth_alloc_urbs(struct iphe
|
||||
if (rx_urb == NULL)
|
||||
goto free_tx_urb;
|
||||
|
||||
- tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE,
|
||||
+ tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_TX_BUF_SIZE,
|
||||
GFP_KERNEL, &tx_urb->transfer_dma);
|
||||
if (tx_buf == NULL)
|
||||
goto free_rx_urb;
|
||||
|
||||
- rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
|
||||
+ rx_buf = usb_alloc_coherent(iphone->udev, iphone->rx_buf_len,
|
||||
GFP_KERNEL, &rx_urb->transfer_dma);
|
||||
if (rx_buf == NULL)
|
||||
goto free_tx_buf;
|
||||
@@ -134,7 +142,7 @@ static int ipheth_alloc_urbs(struct iphe
|
||||
return 0;
|
||||
|
||||
free_tx_buf:
|
||||
- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
|
||||
+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, tx_buf,
|
||||
tx_urb->transfer_dma);
|
||||
free_rx_urb:
|
||||
usb_free_urb(rx_urb);
|
||||
@@ -146,9 +154,9 @@ error_nomem:
|
||||
|
||||
static void ipheth_free_urbs(struct ipheth_device *iphone)
|
||||
{
|
||||
- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf,
|
||||
+ usb_free_coherent(iphone->udev, iphone->rx_buf_len, iphone->rx_buf,
|
||||
iphone->rx_urb->transfer_dma);
|
||||
- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
|
||||
+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, iphone->tx_buf,
|
||||
iphone->tx_urb->transfer_dma);
|
||||
usb_free_urb(iphone->rx_urb);
|
||||
usb_free_urb(iphone->tx_urb);
|
||||
@@ -160,15 +168,106 @@ static void ipheth_kill_urbs(struct iphe
|
||||
usb_kill_urb(dev->rx_urb);
|
||||
}
|
||||
|
||||
-static void ipheth_rcvbulk_callback(struct urb *urb)
|
||||
+static int ipheth_consume_skb(char *buf, int len, struct ipheth_device *dev)
|
||||
{
|
||||
- struct ipheth_device *dev;
|
||||
struct sk_buff *skb;
|
||||
- int status;
|
||||
+
|
||||
+ skb = dev_alloc_skb(len);
|
||||
+ if (!skb) {
|
||||
+ dev->net->stats.rx_dropped++;
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ skb_put_data(skb, buf, len);
|
||||
+ skb->dev = dev->net;
|
||||
+ skb->protocol = eth_type_trans(skb, dev->net);
|
||||
+
|
||||
+ dev->net->stats.rx_packets++;
|
||||
+ dev->net->stats.rx_bytes += len;
|
||||
+ netif_rx(skb);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ipheth_rcvbulk_callback_legacy(struct urb *urb)
|
||||
+{
|
||||
+ struct ipheth_device *dev;
|
||||
+ char *buf;
|
||||
+ int len;
|
||||
+
|
||||
+ dev = urb->context;
|
||||
+
|
||||
+ if (urb->actual_length <= IPHETH_IP_ALIGN) {
|
||||
+ dev->net->stats.rx_length_errors++;
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ len = urb->actual_length - IPHETH_IP_ALIGN;
|
||||
+ buf = urb->transfer_buffer + IPHETH_IP_ALIGN;
|
||||
+
|
||||
+ return ipheth_consume_skb(buf, len, dev);
|
||||
+}
|
||||
+
|
||||
+static int ipheth_rcvbulk_callback_ncm(struct urb *urb)
|
||||
+{
|
||||
+ struct usb_cdc_ncm_nth16 *ncmh;
|
||||
+ struct usb_cdc_ncm_ndp16 *ncm0;
|
||||
+ struct usb_cdc_ncm_dpe16 *dpe;
|
||||
+ struct ipheth_device *dev;
|
||||
+ int retval = -EINVAL;
|
||||
char *buf;
|
||||
int len;
|
||||
|
||||
dev = urb->context;
|
||||
+
|
||||
+ if (urb->actual_length < IPHETH_NCM_HEADER_SIZE) {
|
||||
+ dev->net->stats.rx_length_errors++;
|
||||
+ return retval;
|
||||
+ }
|
||||
+
|
||||
+ ncmh = urb->transfer_buffer;
|
||||
+ if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) ||
|
||||
+ le16_to_cpu(ncmh->wNdpIndex) >= urb->actual_length) {
|
||||
+ dev->net->stats.rx_errors++;
|
||||
+ return retval;
|
||||
+ }
|
||||
+
|
||||
+ ncm0 = urb->transfer_buffer + le16_to_cpu(ncmh->wNdpIndex);
|
||||
+ if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN) ||
|
||||
+ le16_to_cpu(ncmh->wHeaderLength) + le16_to_cpu(ncm0->wLength) >=
|
||||
+ urb->actual_length) {
|
||||
+ dev->net->stats.rx_errors++;
|
||||
+ return retval;
|
||||
+ }
|
||||
+
|
||||
+ dpe = ncm0->dpe16;
|
||||
+ while (le16_to_cpu(dpe->wDatagramIndex) != 0 &&
|
||||
+ le16_to_cpu(dpe->wDatagramLength) != 0) {
|
||||
+ if (le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length ||
|
||||
+ le16_to_cpu(dpe->wDatagramIndex) +
|
||||
+ le16_to_cpu(dpe->wDatagramLength) > urb->actual_length) {
|
||||
+ dev->net->stats.rx_length_errors++;
|
||||
+ return retval;
|
||||
+ }
|
||||
+
|
||||
+ buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex);
|
||||
+ len = le16_to_cpu(dpe->wDatagramLength);
|
||||
+
|
||||
+ retval = ipheth_consume_skb(buf, len, dev);
|
||||
+ if (retval != 0)
|
||||
+ return retval;
|
||||
+
|
||||
+ dpe++;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void ipheth_rcvbulk_callback(struct urb *urb)
|
||||
+{
|
||||
+ struct ipheth_device *dev;
|
||||
+ int retval, status;
|
||||
+
|
||||
+ dev = urb->context;
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
||||
@@ -191,25 +290,27 @@ static void ipheth_rcvbulk_callback(stru
|
||||
dev->net->stats.rx_length_errors++;
|
||||
return;
|
||||
}
|
||||
- len = urb->actual_length - IPHETH_IP_ALIGN;
|
||||
- buf = urb->transfer_buffer + IPHETH_IP_ALIGN;
|
||||
|
||||
- skb = dev_alloc_skb(len);
|
||||
- if (!skb) {
|
||||
- dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n",
|
||||
- __func__);
|
||||
- dev->net->stats.rx_dropped++;
|
||||
+ /* RX URBs starting with 0x00 0x01 do not encapsulate Ethernet frames,
|
||||
+ * but rather are control frames. Their purpose is not documented, and
|
||||
+ * they don't affect driver functionality, okay to drop them.
|
||||
+ * There is usually just one 4-byte control frame as the very first
|
||||
+ * URB received from the bulk IN endpoint.
|
||||
+ */
|
||||
+ if (unlikely
|
||||
+ (((char *)urb->transfer_buffer)[0] == 0 &&
|
||||
+ ((char *)urb->transfer_buffer)[1] == 1))
|
||||
+ goto rx_submit;
|
||||
+
|
||||
+ retval = dev->rcvbulk_callback(urb);
|
||||
+ if (retval != 0) {
|
||||
+ dev_err(&dev->intf->dev, "%s: callback retval: %d\n",
|
||||
+ __func__, retval);
|
||||
return;
|
||||
}
|
||||
|
||||
- skb_put_data(skb, buf, len);
|
||||
- skb->dev = dev->net;
|
||||
- skb->protocol = eth_type_trans(skb, dev->net);
|
||||
-
|
||||
- dev->net->stats.rx_packets++;
|
||||
- dev->net->stats.rx_bytes += len;
|
||||
+rx_submit:
|
||||
dev->confirmed_pairing = true;
|
||||
- netif_rx(skb);
|
||||
ipheth_rx_submit(dev, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
@@ -310,6 +411,27 @@ static int ipheth_get_macaddr(struct iph
|
||||
return retval;
|
||||
}
|
||||
|
||||
+static int ipheth_enable_ncm(struct ipheth_device *dev)
|
||||
+{
|
||||
+ struct usb_device *udev = dev->udev;
|
||||
+ int retval;
|
||||
+
|
||||
+ retval = usb_control_msg(udev,
|
||||
+ usb_sndctrlpipe(udev, IPHETH_CTRL_ENDP),
|
||||
+ IPHETH_CMD_ENABLE_NCM, /* request */
|
||||
+ 0x41, /* request type */
|
||||
+ 0x00, /* value */
|
||||
+ 0x02, /* index */
|
||||
+ NULL,
|
||||
+ 0,
|
||||
+ IPHETH_CTRL_TIMEOUT);
|
||||
+
|
||||
+ dev_info(&dev->intf->dev, "%s: usb_control_msg: %d\n",
|
||||
+ __func__, retval);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
|
||||
{
|
||||
struct usb_device *udev = dev->udev;
|
||||
@@ -317,7 +439,7 @@ static int ipheth_rx_submit(struct iphet
|
||||
|
||||
usb_fill_bulk_urb(dev->rx_urb, udev,
|
||||
usb_rcvbulkpipe(udev, dev->bulk_in),
|
||||
- dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN,
|
||||
+ dev->rx_buf, dev->rx_buf_len,
|
||||
ipheth_rcvbulk_callback,
|
||||
dev);
|
||||
dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
@@ -365,7 +487,7 @@ static netdev_tx_t ipheth_tx(struct sk_b
|
||||
int retval;
|
||||
|
||||
/* Paranoid */
|
||||
- if (skb->len > IPHETH_BUF_SIZE) {
|
||||
+ if (skb->len > IPHETH_TX_BUF_SIZE) {
|
||||
WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
|
||||
dev->net->stats.tx_dropped++;
|
||||
dev_kfree_skb_any(skb);
|
||||
@@ -448,6 +570,8 @@ static int ipheth_probe(struct usb_inter
|
||||
dev->net = netdev;
|
||||
dev->intf = intf;
|
||||
dev->confirmed_pairing = false;
|
||||
+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_LEGACY;
|
||||
+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_legacy;
|
||||
/* Set up endpoints */
|
||||
hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
|
||||
if (hintf == NULL) {
|
||||
@@ -479,6 +603,12 @@ static int ipheth_probe(struct usb_inter
|
||||
if (retval)
|
||||
goto err_get_macaddr;
|
||||
|
||||
+ retval = ipheth_enable_ncm(dev);
|
||||
+ if (!retval) {
|
||||
+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_NCM;
|
||||
+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_ncm;
|
||||
+ }
|
||||
+
|
||||
INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work);
|
||||
|
||||
retval = ipheth_alloc_urbs(dev);
|
@ -0,0 +1,36 @@
|
||||
From 0c6e9d32ef0ccfcf2d875cbcff23bf345a54d585 Mon Sep 17 00:00:00 2001
|
||||
From: Foster Snowhill <forst@pen.gy>
|
||||
Date: Wed, 7 Jun 2023 15:57:02 +0200
|
||||
Subject: [PATCH 4/4] usbnet: ipheth: update Kconfig description
|
||||
|
||||
This module has for a long time not been limited to iPhone <= 3GS.
|
||||
Update description to match the actual state of the driver.
|
||||
|
||||
Remove dead link from 2010, instead reference an existing userspace
|
||||
iOS device pairing implementation as part of libimobiledevice.
|
||||
|
||||
Signed-off-by: Foster Snowhill <forst@pen.gy>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/usb/Kconfig | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/usb/Kconfig
|
||||
+++ b/drivers/net/usb/Kconfig
|
||||
@@ -582,12 +582,10 @@ config USB_IPHETH
|
||||
default n
|
||||
help
|
||||
Module used to share Internet connection (tethering) from your
|
||||
- iPhone (Original, 3G and 3GS) to your system.
|
||||
- Note that you need userspace libraries and programs that are needed
|
||||
- to pair your device with your system and that understand the iPhone
|
||||
- protocol.
|
||||
-
|
||||
- For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
|
||||
+ iPhone to your system.
|
||||
+ Note that you need a corresponding userspace library/program
|
||||
+ to pair your device with your system, for example usbmuxd
|
||||
+ <https://github.com/libimobiledevice/usbmuxd>.
|
||||
|
||||
config USB_SIERRA_NET
|
||||
tristate "USB-to-WWAN Driver for Sierra Wireless modems"
|
@ -17,7 +17,7 @@ sunxi_setup_interfaces()
|
||||
lamobo,lamobo-r1)
|
||||
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" wan
|
||||
;;
|
||||
olimex,a20-olinuxino-micro)
|
||||
olimex,a13-olinuxino-micro)
|
||||
ucidef_set_interface_lan "wlan0"
|
||||
;;
|
||||
xunlong,orangepi-r1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user