gl-infra-builder-FUjr/patches-wlan-ap/0012-ipq807x-fix-tethering-ipheth.patch
Jianhui Zhao 3fbc3ec336 ax1800/axt1800: upgrade wlan-ap to v2.6.0
Signed-off-by: Jianhui Zhao <jianhui.zhao@gl-inet.com>
2022-07-12 16:43:39 +08:00

214 lines
6.0 KiB
Diff

From 12426b29d67c759c44e7a4ec0adea7dc0c98c486 Mon Sep 17 00:00:00 2001
From: Jianhui Zhao <jianhui.zhao@gl-inet.com>
Date: Tue, 12 Jul 2022 12:20:54 +0800
Subject: [PATCH] ipq807x: fix tethering ipheth
Signed-off-by: Jianhui Zhao <jianhui.zhao@gl-inet.com>
---
.../patches/201-fix-tethering-ipheth.patch | 193 ++++++++++++++++++
1 file changed, 193 insertions(+)
create mode 100644 feeds/ipq807x/ipq807x/patches/201-fix-tethering-ipheth.patch
diff --git a/feeds/ipq807x/ipq807x/patches/201-fix-tethering-ipheth.patch b/feeds/ipq807x/ipq807x/patches/201-fix-tethering-ipheth.patch
new file mode 100644
index 00000000..2b43b132
--- /dev/null
+++ b/feeds/ipq807x/ipq807x/patches/201-fix-tethering-ipheth.patch
@@ -0,0 +1,193 @@
+--- a/drivers/net/usb/ipheth.c
++++ b/drivers/net/usb/ipheth.c
+@@ -70,7 +70,7 @@
+ #define IPHETH_USBINTF_SUBCLASS 253
+ #define IPHETH_USBINTF_PROTO 1
+
+-#define IPHETH_BUF_SIZE 1516
++#define IPHETH_BUF_SIZE 1514
+ #define IPHETH_IP_ALIGN 2 /* padding at front of URB */
+ #define IPHETH_TX_TIMEOUT (5 * HZ)
+
+@@ -87,7 +87,7 @@
+ #define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
+ #define IPHETH_CARRIER_ON 0x04
+
+-static struct usb_device_id ipheth_table[] = {
++static const struct usb_device_id ipheth_table[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(
+ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE,
+ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+@@ -140,7 +140,6 @@ struct ipheth_device {
+ struct usb_device *udev;
+ struct usb_interface *intf;
+ struct net_device *net;
+- struct sk_buff *tx_skb;
+ struct urb *tx_urb;
+ struct urb *rx_urb;
+ unsigned char *tx_buf;
+@@ -149,6 +148,8 @@ struct ipheth_device {
+ u8 bulk_in;
+ u8 bulk_out;
+ struct delayed_work carrier_work;
++ bool confirmed_pairing;
++ int tx_in_use;
+ };
+
+ static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
+@@ -229,6 +230,7 @@ static void ipheth_rcvbulk_callback(stru
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ESHUTDOWN:
++ case -EPROTO:
+ return;
+ case 0:
+ break;
+@@ -253,13 +255,13 @@ static void ipheth_rcvbulk_callback(stru
+ return;
+ }
+
+- memcpy(skb_put(skb, len), buf, len);
++ 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;
+-
++ dev->confirmed_pairing = true;
+ netif_rx(skb);
+ ipheth_rx_submit(dev, GFP_ATOMIC);
+ }
+@@ -280,15 +282,26 @@ static void ipheth_sndbulk_callback(stru
+ dev_err(&dev->intf->dev, "%s: urb status: %d\n",
+ __func__, status);
+
+- dev_kfree_skb_irq(dev->tx_skb);
+- netif_wake_queue(dev->net);
++ dev->tx_in_use = false;
++
++ if (status == 0)
++ netif_wake_queue(dev->net);
++ else
++ // on URB error, trigger immediate poll
++ schedule_delayed_work(&dev->carrier_work, 0);
+ }
+
+ static int ipheth_carrier_set(struct ipheth_device *dev)
+ {
+- struct usb_device *udev = dev->udev;
++ struct usb_device *udev;
+ int retval;
+
++ if (!dev)
++ return 0;
++ if (!dev->confirmed_pairing)
++ return 0;
++
++ udev = dev->udev;
+ retval = usb_control_msg(udev,
+ usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
+ IPHETH_CMD_CARRIER_CHECK, /* request */
+@@ -303,11 +316,14 @@ static int ipheth_carrier_set(struct iph
+ return retval;
+ }
+
+- if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON)
++ if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON) {
+ netif_carrier_on(dev->net);
+- else
++ if (dev->tx_urb->status != -EINPROGRESS && dev->tx_in_use == false)
++ netif_wake_queue(dev->net);
++ } else {
+ netif_carrier_off(dev->net);
+-
++ netif_stop_queue(dev->net);
++ }
+ return 0;
+ }
+
+@@ -376,6 +392,8 @@ static int ipheth_open(struct net_device
+ struct usb_device *udev = dev->udev;
+ int retval = 0;
+
++ dev->tx_in_use = false;
++
+ usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM);
+
+ retval = ipheth_carrier_set(dev);
+@@ -387,7 +405,6 @@ static int ipheth_open(struct net_device
+ return retval;
+
+ schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
+- netif_start_queue(net);
+ return retval;
+ }
+
+@@ -410,10 +427,18 @@ static int ipheth_tx(struct sk_buff *skb
+ if (skb->len > IPHETH_BUF_SIZE) {
+ WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
+ dev->net->stats.tx_dropped++;
+- dev_kfree_skb_irq(skb);
++ dev_kfree_skb_any(skb);
++ return NETDEV_TX_OK;
++ }
++
++ if (dev->tx_in_use) {
++ dev->net->stats.tx_dropped++;
++ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
++ dev->tx_in_use = true;
++
+ 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);
+@@ -425,18 +450,22 @@ static int ipheth_tx(struct sk_buff *skb
+ dev);
+ dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
++ netif_stop_queue(net);
+ retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);
+ if (retval) {
+ dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n",
+ __func__, retval);
+ dev->net->stats.tx_errors++;
+- dev_kfree_skb_irq(skb);
++ dev_kfree_skb_any(skb);
++ netif_wake_queue(net);
++ if (atomic_read(&dev->tx_urb->use_count) != 0) {
++ atomic_dec(&dev->tx_urb->use_count);
++ }
++ dev->tx_in_use = false;
+ } else {
+- dev->tx_skb = skb;
+-
+ dev->net->stats.tx_packets++;
+ dev->net->stats.tx_bytes += skb->len;
+- netif_stop_queue(net);
++ dev_consume_skb_any(skb);
+ }
+
+ return NETDEV_TX_OK;
+@@ -491,7 +520,7 @@ static int ipheth_probe(struct usb_inter
+ dev->udev = udev;
+ dev->net = netdev;
+ dev->intf = intf;
+-
++ dev->confirmed_pairing = false;
+ /* Set up endpoints */
+ hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
+ if (hintf == NULL) {
+@@ -542,7 +571,9 @@ static int ipheth_probe(struct usb_inter
+ retval = -EIO;
+ goto err_register_netdev;
+ }
+-
++ // carrier down and transmit queues stopped until packet from device
++ netif_carrier_off(netdev);
++ netif_tx_stop_all_queues(netdev);
+ dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n");
+ return 0;
+
--
2.25.1