diff --git a/target/linux/generic/patches-4.4/099-0001-usbnet-allow-mini-drivers-to-consume-L2-headers.patch b/target/linux/generic/patches-4.4/099-0001-usbnet-allow-mini-drivers-to-consume-L2-headers.patch
new file mode 100644
index 000000000000..a1f19ea18e9b
--- /dev/null
+++ b/target/linux/generic/patches-4.4/099-0001-usbnet-allow-mini-drivers-to-consume-L2-headers.patch
@@ -0,0 +1,39 @@
+From 81e0ce79f2919dbd5f025894d29aa806af8695c7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Thu, 3 Dec 2015 19:24:20 +0100
+Subject: [PATCH] usbnet: allow mini-drivers to consume L2 headers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Assume the minidriver has taken care of all L2 header parsing
+if it sets skb->protocol.  This allows the minidriver to
+support non-ethernet L2 headers, and even operate without
+any L2 header at all.
+
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/usbnet.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 0744bf2ef2d6..0b0ba7ef14e4 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -324,7 +324,10 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
+ 		return;
+ 	}
+ 
+-	skb->protocol = eth_type_trans (skb, dev->net);
++	/* only update if unset to allow minidriver rx_fixup override */
++	if (skb->protocol == 0)
++		skb->protocol = eth_type_trans (skb, dev->net);
++
+ 	dev->net->stats.rx_packets++;
+ 	dev->net->stats.rx_bytes += skb->len;
+ 
+-- 
+2.7.4
+
diff --git a/target/linux/generic/patches-4.4/099-0002-net-qmi_wwan-support-raw-IP-mode.patch b/target/linux/generic/patches-4.4/099-0002-net-qmi_wwan-support-raw-IP-mode.patch
new file mode 100644
index 000000000000..8b5fc374b37c
--- /dev/null
+++ b/target/linux/generic/patches-4.4/099-0002-net-qmi_wwan-support-raw-IP-mode.patch
@@ -0,0 +1,206 @@
+From 32f7adf633b9f99ad5089901bc7ebff57704aaa9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Thu, 3 Dec 2015 19:24:21 +0100
+Subject: [PATCH] net: qmi_wwan: support "raw IP" mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+QMI wwan devices have traditionally emulated ethernet devices
+by default. But they have always had the capability of operating
+without any L2 header at all, transmitting and receiving "raw"
+IP packets over the USB link.  This firmware feature used to be
+configurable through the QMI management protocol.
+
+Traditionally there was no way to verify the firmware mode
+without attempting to change it.  And the firmware would often
+disallow changes anyway, i.e. due to a session already being
+established.  In some cases, this could be a hidden firmware
+internal session, completely outside host control.  For these
+reasons, sticking with the "well known" default mode was safest.
+
+But newer generations of QMI hardware and firmware have moved
+towards defaulting to "raw IP" mode instead, followed by an
+increasing number of bugs in the already buggy "802.3" firmware
+implementation. At the same time, the QMI management protocol
+gained the ability to detect the current mode.  This has enabled
+the userspace QMI management application to verify the current
+firmware mode without trying to modify it.
+
+Following this development, the latest QMI hardware and firmware
+(the MDM9x30 generation) has dropped support for "802.3" mode
+entirely. Support for "raw IP" framing in the driver is therefore
+necessary for these devices, and to a certain degree to work
+around problems with the previous generation,
+
+This patch adds support for "raw IP" framing for QMI devices,
+changing the netdev from an ethernet device to an ARPHRD_NONE
+p-t-p device when "raw IP" framing is enabled.
+
+The firmware setup is fully delegated to the QMI userspace
+management application, through simple tunneling of the QMI
+protocol. The driver will therefore not know which mode has been
+"negotiated" between firmware and userspace. Allowing userspace
+to inform the driver of the result through a sysfs switch is
+considered a better alternative than to change the well established
+clean delegation of firmware management to userspace.
+
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/qmi_wwan.c | 98 +++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 97 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index e3727b66d850..98add3bf8821 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -14,6 +14,7 @@
+ #include <linux/netdevice.h>
+ #include <linux/ethtool.h>
+ #include <linux/etherdevice.h>
++#include <linux/if_arp.h>
+ #include <linux/mii.h>
+ #include <linux/usb.h>
+ #include <linux/usb/cdc.h>
+@@ -48,11 +49,93 @@
+ struct qmi_wwan_state {
+ 	struct usb_driver *subdriver;
+ 	atomic_t pmcount;
+-	unsigned long unused;
++	unsigned long flags;
+ 	struct usb_interface *control;
+ 	struct usb_interface *data;
+ };
+ 
++enum qmi_wwan_flags {
++	QMI_WWAN_FLAG_RAWIP = 1 << 0,
++};
++
++static void qmi_wwan_netdev_setup(struct net_device *net)
++{
++	struct usbnet *dev = netdev_priv(net);
++	struct qmi_wwan_state *info = (void *)&dev->data;
++
++	if (info->flags & QMI_WWAN_FLAG_RAWIP) {
++		net->header_ops      = NULL;  /* No header */
++		net->type            = ARPHRD_NONE;
++		net->hard_header_len = 0;
++		net->addr_len        = 0;
++		net->flags           = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
++		netdev_dbg(net, "mode: raw IP\n");
++	} else if (!net->header_ops) { /* don't bother if already set */
++		ether_setup(net);
++		netdev_dbg(net, "mode: Ethernet\n");
++	}
++
++	/* recalculate buffers after changing hard_header_len */
++	usbnet_change_mtu(net, net->mtu);
++}
++
++static ssize_t raw_ip_show(struct device *d, struct device_attribute *attr, char *buf)
++{
++	struct usbnet *dev = netdev_priv(to_net_dev(d));
++	struct qmi_wwan_state *info = (void *)&dev->data;
++
++	return sprintf(buf, "%c\n", info->flags & QMI_WWAN_FLAG_RAWIP ? 'Y' : 'N');
++}
++
++static ssize_t raw_ip_store(struct device *d,  struct device_attribute *attr, const char *buf, size_t len)
++{
++	struct usbnet *dev = netdev_priv(to_net_dev(d));
++	struct qmi_wwan_state *info = (void *)&dev->data;
++	bool enable;
++	int err;
++
++	if (strtobool(buf, &enable))
++		return -EINVAL;
++
++	/* no change? */
++	if (enable == (info->flags & QMI_WWAN_FLAG_RAWIP))
++		return len;
++
++	/* we don't want to modify a running netdev */
++	if (netif_running(dev->net)) {
++		netdev_err(dev->net, "Cannot change a running device\n");
++		return -EBUSY;
++	}
++
++	/* let other drivers deny the change */
++	err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net);
++	err = notifier_to_errno(err);
++	if (err) {
++		netdev_err(dev->net, "Type change was refused\n");
++		return err;
++	}
++
++	if (enable)
++		info->flags |= QMI_WWAN_FLAG_RAWIP;
++	else
++		info->flags &= ~QMI_WWAN_FLAG_RAWIP;
++	qmi_wwan_netdev_setup(dev->net);
++	call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev->net);
++	return len;
++}
++
++static DEVICE_ATTR_RW(raw_ip);
++
++static struct attribute *qmi_wwan_sysfs_attrs[] = {
++	&dev_attr_raw_ip.attr,
++	NULL,
++};
++
++static struct attribute_group qmi_wwan_sysfs_attr_group = {
++	.name = "qmi",
++	.attrs = qmi_wwan_sysfs_attrs,
++};
++
+ /* default ethernet address used by the modem */
+ static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3};
+ 
+@@ -80,6 +163,8 @@ static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00};
+  */
+ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+ {
++	struct qmi_wwan_state *info = (void *)&dev->data;
++	bool rawip = info->flags & QMI_WWAN_FLAG_RAWIP;
+ 	__be16 proto;
+ 
+ 	/* This check is no longer done by usbnet */
+@@ -94,15 +179,25 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+ 		proto = htons(ETH_P_IPV6);
+ 		break;
+ 	case 0x00:
++		if (rawip)
++			return 0;
+ 		if (is_multicast_ether_addr(skb->data))
+ 			return 1;
+ 		/* possibly bogus destination - rewrite just in case */
+ 		skb_reset_mac_header(skb);
+ 		goto fix_dest;
+ 	default:
++		if (rawip)
++			return 0;
+ 		/* pass along other packets without modifications */
+ 		return 1;
+ 	}
++	if (rawip) {
++		skb->dev = dev->net; /* normally set by eth_type_trans */
++		skb->protocol = proto;
++		return 1;
++	}
++
+ 	if (skb_headroom(skb) < ETH_HLEN)
+ 		return 0;
+ 	skb_push(skb, ETH_HLEN);
+@@ -326,6 +421,7 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
+ 		dev->net->dev_addr[0] &= 0xbf;	/* clear "IP" bit */
+ 	}
+ 	dev->net->netdev_ops = &qmi_wwan_netdev_ops;
++	dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group;
+ err:
+ 	return status;
+ }
+-- 
+2.7.4
+
diff --git a/target/linux/generic/patches-4.4/099-0003-net-qmi_wwan-should-hold-RTNL-while-changing-netdev-.patch b/target/linux/generic/patches-4.4/099-0003-net-qmi_wwan-should-hold-RTNL-while-changing-netdev-.patch
new file mode 100644
index 000000000000..48f7141efb61
--- /dev/null
+++ b/target/linux/generic/patches-4.4/099-0003-net-qmi_wwan-should-hold-RTNL-while-changing-netdev-.patch
@@ -0,0 +1,107 @@
+From 6c730080e663b1d629f8aa89348291fbcdc46cd9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Sun, 6 Dec 2015 21:25:50 +0100
+Subject: [PATCH] net: qmi_wwan: should hold RTNL while changing netdev type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The notifier calls were thrown in as a last-minute fix for an
+imagined "this device could be part of a bridge" problem. That
+revealed a certain lack of locking.  Not to mention testing...
+
+Avoid this splat:
+
+RTNL: assertion failed at net/core/dev.c (1639)
+CPU: 0 PID: 4293 Comm: bash Not tainted 4.4.0-rc3+ #358
+Hardware name: LENOVO 2776LEG/2776LEG, BIOS 6EET55WW (3.15 ) 12/19/2011
+ 0000000000000000 ffff8800ad253d60 ffffffff8122f7cf ffff8800ad253d98
+ ffff8800ad253d88 ffffffff813833ab 0000000000000002 ffff880230f48560
+ ffff880230a12900 ffff8800ad253da0 ffffffff813833da 0000000000000002
+Call Trace:
+ [<ffffffff8122f7cf>] dump_stack+0x4b/0x63
+ [<ffffffff813833ab>] call_netdevice_notifiers_info+0x3d/0x59
+ [<ffffffff813833da>] call_netdevice_notifiers+0x13/0x15
+ [<ffffffffa09be227>] raw_ip_store+0x81/0x193 [qmi_wwan]
+ [<ffffffff8131e149>] dev_attr_store+0x20/0x22
+ [<ffffffff811d858b>] sysfs_kf_write+0x49/0x50
+ [<ffffffff811d8027>] kernfs_fop_write+0x10a/0x151
+ [<ffffffff8117249a>] __vfs_write+0x26/0xa5
+ [<ffffffff81085ed4>] ? percpu_down_read+0x53/0x7f
+ [<ffffffff81174c9e>] ? __sb_start_write+0x5f/0xb0
+ [<ffffffff81174c9e>] ? __sb_start_write+0x5f/0xb0
+ [<ffffffff81172c37>] vfs_write+0xa3/0xe7
+ [<ffffffff811734ad>] SyS_write+0x50/0x7e
+ [<ffffffff8145c517>] entry_SYSCALL_64_fastpath+0x12/0x6f
+
+Fixes: 32f7adf633b9 ("net: qmi_wwan: support "raw IP" mode")
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/qmi_wwan.c | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 98add3bf8821..babc84a3946c 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -16,6 +16,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/if_arp.h>
+ #include <linux/mii.h>
++#include <linux/rtnetlink.h>
+ #include <linux/usb.h>
+ #include <linux/usb/cdc.h>
+ #include <linux/usb/usbnet.h>
+@@ -92,7 +93,7 @@ static ssize_t raw_ip_store(struct device *d,  struct device_attribute *attr, co
+ 	struct usbnet *dev = netdev_priv(to_net_dev(d));
+ 	struct qmi_wwan_state *info = (void *)&dev->data;
+ 	bool enable;
+-	int err;
++	int ret;
+ 
+ 	if (strtobool(buf, &enable))
+ 		return -EINVAL;
+@@ -101,18 +102,22 @@ static ssize_t raw_ip_store(struct device *d,  struct device_attribute *attr, co
+ 	if (enable == (info->flags & QMI_WWAN_FLAG_RAWIP))
+ 		return len;
+ 
++	if (!rtnl_trylock())
++		return restart_syscall();
++
+ 	/* we don't want to modify a running netdev */
+ 	if (netif_running(dev->net)) {
+ 		netdev_err(dev->net, "Cannot change a running device\n");
+-		return -EBUSY;
++		ret = -EBUSY;
++		goto err;
+ 	}
+ 
+ 	/* let other drivers deny the change */
+-	err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net);
+-	err = notifier_to_errno(err);
+-	if (err) {
++	ret = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net);
++	ret = notifier_to_errno(ret);
++	if (ret) {
+ 		netdev_err(dev->net, "Type change was refused\n");
+-		return err;
++		goto err;
+ 	}
+ 
+ 	if (enable)
+@@ -121,7 +126,10 @@ static ssize_t raw_ip_store(struct device *d,  struct device_attribute *attr, co
+ 		info->flags &= ~QMI_WWAN_FLAG_RAWIP;
+ 	qmi_wwan_netdev_setup(dev->net);
+ 	call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev->net);
+-	return len;
++	ret = len;
++err:
++	rtnl_unlock();
++	return ret;
+ }
+ 
+ static DEVICE_ATTR_RW(raw_ip);
+-- 
+2.7.4
+
diff --git a/target/linux/generic/patches-4.4/099-0004-usbnet-fix-alignment-for-frames-with-no-ethernet-hea.patch b/target/linux/generic/patches-4.4/099-0004-usbnet-fix-alignment-for-frames-with-no-ethernet-hea.patch
new file mode 100644
index 000000000000..2511e0a9614b
--- /dev/null
+++ b/target/linux/generic/patches-4.4/099-0004-usbnet-fix-alignment-for-frames-with-no-ethernet-hea.patch
@@ -0,0 +1,73 @@
+From a4abd7a80addb4a9547f7dfc7812566b60ec505c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Wed, 6 Dec 2017 20:21:24 +0100
+Subject: [PATCH] usbnet: fix alignment for frames with no ethernet header
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The qmi_wwan minidriver support a 'raw-ip' mode where frames are
+received without any ethernet header. This causes alignment issues
+because the skbs allocated by usbnet are "IP aligned".
+
+Fix by allowing minidrivers to disable the additional alignment
+offset. This is implemented using a per-device flag, since the same
+minidriver also supports 'ethernet' mode.
+
+Fixes: 32f7adf633b9 ("net: qmi_wwan: support "raw IP" mode")
+Reported-and-tested-by: Jay Foster <jay@systech.com>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/qmi_wwan.c | 2 ++
+ drivers/net/usb/usbnet.c   | 5 ++++-
+ include/linux/usb/usbnet.h | 1 +
+ 3 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index c750cf7c042b..304ec6555cd8 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -261,9 +261,11 @@ static void qmi_wwan_netdev_setup(struct net_device *net)
+ 		net->hard_header_len = 0;
+ 		net->addr_len        = 0;
+ 		net->flags           = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
++		set_bit(EVENT_NO_IP_ALIGN, &dev->flags);
+ 		netdev_dbg(net, "mode: raw IP\n");
+ 	} else if (!net->header_ops) { /* don't bother if already set */
+ 		ether_setup(net);
++		clear_bit(EVENT_NO_IP_ALIGN, &dev->flags);
+ 		netdev_dbg(net, "mode: Ethernet\n");
+ 	}
+ 
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 80348b6a8646..d56fe32bf48d 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -484,7 +484,10 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
+ 		return -ENOLINK;
+ 	}
+ 
+-	skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
++	if (test_bit(EVENT_NO_IP_ALIGN, &dev->flags))
++		skb = __netdev_alloc_skb(dev->net, size, flags);
++	else
++		skb = __netdev_alloc_skb_ip_align(dev->net, size, flags);
+ 	if (!skb) {
+ 		netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
+ 		usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
+diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
+index a69877734c4e..e2ec3582e549 100644
+--- a/include/linux/usb/usbnet.h
++++ b/include/linux/usb/usbnet.h
+@@ -82,6 +82,7 @@ struct usbnet {
+ #		define EVENT_RX_KILL	10
+ #		define EVENT_LINK_CHANGE	11
+ #		define EVENT_SET_RX_MODE	12
++#		define EVENT_NO_IP_ALIGN	13
+ };
+ 
+ static inline struct usb_driver *driver_of(struct usb_interface *intf)
+-- 
+2.7.4
+
diff --git a/target/linux/generic/patches-4.4/099-0005-qmi_wwan-Add-missing-skb_reset_mac_header-call.patch b/target/linux/generic/patches-4.4/099-0005-qmi_wwan-Add-missing-skb_reset_mac_header-call.patch
new file mode 100644
index 000000000000..08408e2414d1
--- /dev/null
+++ b/target/linux/generic/patches-4.4/099-0005-qmi_wwan-Add-missing-skb_reset_mac_header-call.patch
@@ -0,0 +1,81 @@
+From 0de0add10e587effa880c741c9413c874f16be91 Mon Sep 17 00:00:00 2001
+From: Kristian Evensen <kristian.evensen@gmail.com>
+Date: Tue, 7 Nov 2017 13:47:56 +0100
+Subject: [PATCH] qmi_wwan: Add missing skb_reset_mac_header-call
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When we receive a packet on a QMI device in raw IP mode, we should call
+skb_reset_mac_header() to ensure that skb->mac_header contains a valid
+offset in the packet. While it shouldn't really matter, the packets have
+no MAC header and the interface is configured as-such, it seems certain
+parts of the network stack expects a "good" value in skb->mac_header.
+
+Without the skb_reset_mac_header() call added in this patch, for example
+shaping traffic (using tc) triggers the following oops on the first
+received packet:
+
+[  303.642957] skbuff: skb_under_panic: text:8f137918 len:177 put:67 head:8e4b0f00 data:8e4b0eff tail:0x8e4b0fb0 end:0x8e4b1520 dev:wwan0
+[  303.655045] Kernel bug detected[#1]:
+[  303.658622] CPU: 1 PID: 1002 Comm: logd Not tainted 4.9.58 #0
+[  303.664339] task: 8fdf05e0 task.stack: 8f15c000
+[  303.668844] $ 0   : 00000000 00000001 0000007a 00000000
+[  303.674062] $ 4   : 8149a2fc 8149a2fc 8149ce20 00000000
+[  303.679284] $ 8   : 00000030 3878303a 31623465 20303235
+[  303.684510] $12   : ded731e3 2626a277 00000000 03bd0000
+[  303.689747] $16   : 8ef62b40 00000043 8f137918 804db5fc
+[  303.694978] $20   : 00000001 00000004 8fc13800 00000003
+[  303.700215] $24   : 00000001 8024ab10
+[  303.705442] $28   : 8f15c000 8fc19cf0 00000043 802cc920
+[  303.710664] Hi    : 00000000
+[  303.713533] Lo    : 74e58000
+[  303.716436] epc   : 802cc920 skb_panic+0x58/0x5c
+[  303.721046] ra    : 802cc920 skb_panic+0x58/0x5c
+[  303.725639] Status: 11007c03 KERNEL EXL IE
+[  303.729823] Cause : 50800024 (ExcCode 09)
+[  303.733817] PrId  : 0001992f (MIPS 1004Kc)
+[  303.737892] Modules linked in: rt2800pci rt2800mmio rt2800lib qcserial ppp_async option usb_wwan rt2x00pci rt2x00mmio rt2x00lib rndis_host qmi_wwan ppp_generic nf_nat_pptp nf_conntrack_pptp nf_conntrack_ipv6 mt76x2i
+Process logd (pid: 1002, threadinfo=8f15c000, task=8fdf05e0, tls=77b3eee4)
+[  303.962509] Stack : 00000000 80408990 8f137918 000000b1 00000043 8e4b0f00 8e4b0eff 8e4b0fb0
+[  303.970871]         8e4b1520 8fec1800 00000043 802cd2a4 6e000045 00000043 00000000 8ef62000
+[  303.979219]         8eef5d00 8ef62b40 8fea7300 8f137918 00000000 00000000 0002bb01 793e5664
+[  303.987568]         8ef08884 00000001 8fea7300 00000002 8fc19e80 8eef5d00 00000006 00000003
+[  303.995934]         00000000 8030ba90 00000003 77ab3fd0 8149dc80 8004d1bc 8f15c000 8f383700
+[  304.004324]         ...
+[  304.006767] Call Trace:
+[  304.009241] [<802cc920>] skb_panic+0x58/0x5c
+[  304.013504] [<802cd2a4>] skb_push+0x78/0x90
+[  304.017783] [<8f137918>] 0x8f137918
+[  304.021269] Code: 00602825  0c02a3b4  24842888 <000c000d> 8c870060  8c8200a0  0007382b  00070336  8c88005c
+[  304.031034]
+[  304.032805] ---[ end trace b778c482b3f0bda9 ]---
+[  304.041384] Kernel panic - not syncing: Fatal exception in interrupt
+[  304.051975] Rebooting in 3 seconds..
+
+While the oops is for a 4.9-kernel, I was able to trigger the same oops with
+net-next as of yesterday.
+
+Fixes: 32f7adf633b9 ("net: qmi_wwan: support "raw IP" mode")
+Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
+Acked-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/qmi_wwan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index a4f229edcceb..8d4a6f7cba61 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -499,6 +499,7 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+ 		return 1;
+ 	}
+ 	if (rawip) {
++		skb_reset_mac_header(skb);
+ 		skb->dev = dev->net; /* normally set by eth_type_trans */
+ 		skb->protocol = proto;
+ 		return 1;
+-- 
+2.7.4
+
diff --git a/target/linux/generic/patches-4.4/099-0006-net-qmi_wwan-MDM9x30-specific-power-management.patch b/target/linux/generic/patches-4.4/099-0006-net-qmi_wwan-MDM9x30-specific-power-management.patch
new file mode 100644
index 000000000000..c26a86b270e0
--- /dev/null
+++ b/target/linux/generic/patches-4.4/099-0006-net-qmi_wwan-MDM9x30-specific-power-management.patch
@@ -0,0 +1,97 @@
+From 93725149794d3d418cf1eddcae60c7b536c5faa1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Thu, 3 Dec 2015 19:24:18 +0100
+Subject: [PATCH] net: qmi_wwan: MDM9x30 specific power management
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+MDM9x30 based modems appear to go into a deeper sleep when
+suspended without "Remote Wakeup" enabled.  The QMI interface
+will not respond unless a "set DTR" control request is sent
+on resume. The effect is similar to a QMI_CTL SYNC request,
+resetting (some of) the firmware state.
+
+We allow userspace sessions to span multiple character device
+open/close sequences.  This means that userspace can depend
+on firmware state while both the netdev and the character
+device are closed.  We have disabled "needs_remote_wakeup" at
+this point to allow devices without remote wakeup support to
+be auto-suspended.
+
+To make sure the MDM9x30 keeps firmware state, we need to
+keep "needs_remote_wakeup" always set. We also need to
+issue a "set DTR" request to enable the QMI interface.
+
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/qmi_wwan.c | 38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 9a5be8b85186..fc9dd452a3b5 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -223,6 +223,20 @@ static int qmi_wwan_register_subdriver(struct usbnet *dev)
+ 	return rv;
+ }
+ 
++/* Send CDC SetControlLineState request, setting or clearing the DTR.
++ * "Required for Autoconnect and 9x30 to wake up" according to the
++ * GobiNet driver. The requirement has been verified on an MDM9230
++ * based Sierra Wireless MC7455
++ */
++static int qmi_wwan_change_dtr(struct usbnet *dev, bool on)
++{
++	u8 intf = dev->intf->cur_altsetting->desc.bInterfaceNumber;
++
++	return usbnet_write_cmd(dev, USB_CDC_REQ_SET_CONTROL_LINE_STATE,
++				USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
++				on ? 0x01 : 0x00, intf, NULL, 0);
++}
++
+ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
+ {
+ 	int status = -1;
+@@ -280,6 +294,24 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
+ 		usb_driver_release_interface(driver, info->data);
+ 	}
+ 
++	/* disabling remote wakeup on MDM9x30 devices has the same
++	 * effect as clearing DTR. The device will not respond to QMI
++	 * requests until we set DTR again.  This is similar to a
++	 * QMI_CTL SYNC request, clearing a lot of firmware state
++	 * including the client ID allocations.
++	 *
++	 * Our usage model allows a session to span multiple
++	 * open/close events, so we must prevent the firmware from
++	 * clearing out state the clients might need.
++	 *
++	 * MDM9x30 is the first QMI chipset with USB3 support. Abuse
++	 * this fact to enable the quirk.
++	 */
++	if (le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) {
++		qmi_wwan_manage_power(dev, 1);
++		qmi_wwan_change_dtr(dev, true);
++	}
++
+ 	/* Never use the same address on both ends of the link, even if the
+ 	 * buggy firmware told us to. Or, if device is assigned the well-known
+ 	 * buggy firmware MAC address, replace it with a random address,
+@@ -307,6 +339,12 @@ static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf)
+ 	if (info->subdriver && info->subdriver->disconnect)
+ 		info->subdriver->disconnect(info->control);
+ 
++	/* disable MDM9x30 quirk */
++	if (le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) {
++		qmi_wwan_change_dtr(dev, false);
++		qmi_wwan_manage_power(dev, 0);
++	}
++
+ 	/* allow user to unbind using either control or data */
+ 	if (intf == info->control)
+ 		other = info->data;
+-- 
+2.7.4
+
diff --git a/target/linux/generic/patches-4.4/099-0007-qmi_wwan-add-support-for-Quectel-EC21-and-EC25.patch b/target/linux/generic/patches-4.4/099-0007-qmi_wwan-add-support-for-Quectel-EC21-and-EC25.patch
new file mode 100644
index 000000000000..3b8032776ac6
--- /dev/null
+++ b/target/linux/generic/patches-4.4/099-0007-qmi_wwan-add-support-for-Quectel-EC21-and-EC25.patch
@@ -0,0 +1,98 @@
+From 9a765881bf3dcd32847d7108cf48cb04a4ed993f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Mon, 10 Oct 2016 21:12:49 +0200
+Subject: [PATCH] qmi_wwan: add support for Quectel EC21 and EC25
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The Quectel EC21 and EC25 need the same "set DTR" request as devices
+based on the MDM9230 chipset, but has no USB3 support. Our best guess
+is that the "set DTR" functionality depends on chipset and/or
+baseband firmware generation. But USB3 is still an optional feature.
+
+Since we cannot enable this unconditionally for all older devices, and
+there doesn't appear to be anything we can use in the USB descriptors
+to identify these chips, we are forced to use a device specific quirk
+flag.
+
+Reported-and-tested-by: Sebastian Sjoholm <sebastian.sjoholm@gmail.com>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/qmi_wwan.c | 30 ++++++++++++++++++++++++++++--
+ 1 file changed, 28 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 9d1fce8a6e84..3ff76c6db4f6 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -59,6 +59,10 @@ enum qmi_wwan_flags {
+ 	QMI_WWAN_FLAG_RAWIP = 1 << 0,
+ };
+ 
++enum qmi_wwan_quirks {
++	QMI_WWAN_QUIRK_DTR = 1 << 0,	/* needs "set DTR" request */
++};
++
+ static void qmi_wwan_netdev_setup(struct net_device *net)
+ {
+ 	struct usbnet *dev = netdev_priv(net);
+@@ -411,9 +415,14 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
+ 	 * clearing out state the clients might need.
+ 	 *
+ 	 * MDM9x30 is the first QMI chipset with USB3 support. Abuse
+-	 * this fact to enable the quirk.
++	 * this fact to enable the quirk for all USB3 devices.
++	 *
++	 * There are also chipsets with the same "set DTR" requirement
++	 * but without USB3 support.  Devices based on these chips
++	 * need a quirk flag in the device ID table.
+ 	 */
+-	if (le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) {
++	if (dev->driver_info->data & QMI_WWAN_QUIRK_DTR ||
++	    le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) {
+ 		qmi_wwan_manage_power(dev, 1);
+ 		qmi_wwan_change_dtr(dev, true);
+ 	}
+@@ -526,6 +535,16 @@ static const struct driver_info	qmi_wwan_info = {
+ 	.rx_fixup       = qmi_wwan_rx_fixup,
+ };
+ 
++static const struct driver_info	qmi_wwan_info_quirk_dtr = {
++	.description	= "WWAN/QMI device",
++	.flags		= FLAG_WWAN,
++	.bind		= qmi_wwan_bind,
++	.unbind		= qmi_wwan_unbind,
++	.manage_power	= qmi_wwan_manage_power,
++	.rx_fixup       = qmi_wwan_rx_fixup,
++	.data           = QMI_WWAN_QUIRK_DTR,
++};
++
+ #define HUAWEI_VENDOR_ID	0x12D1
+ 
+ /* map QMI/wwan function by a fixed interface number */
+@@ -533,6 +552,11 @@ static const struct driver_info	qmi_wwan_info = {
+ 	USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \
+ 	.driver_info = (unsigned long)&qmi_wwan_info
+ 
++/* devices requiring "set DTR" quirk */
++#define QMI_QUIRK_SET_DTR(vend, prod, num) \
++	USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \
++	.driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr
++
+ /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */
+ #define QMI_GOBI1K_DEVICE(vend, prod) \
+ 	QMI_FIXED_INTF(vend, prod, 3)
+@@ -895,6 +919,8 @@ static const struct usb_device_id products[] = {
+ 	{QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)},	/* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
+ 	{QMI_FIXED_INTF(0x22de, 0x9061, 3)},	/* WeTelecom WPD-600N */
+ 	{QMI_FIXED_INTF(0x1e0e, 0x9001, 5)},	/* SIMCom 7230E */
++	{QMI_QUIRK_SET_DTR(0x2c7c, 0x0125, 4)},	/* Quectel EC25, EC20 R2.0  Mini PCIe */
++	{QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)},	/* Quectel EC21 Mini PCIe */
+ 
+ 	/* 4. Gobi 1000 devices */
+ 	{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */
+-- 
+2.7.4
+
