099-0002-net-qmi_wwan-support-raw-IP-mode.patch 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. From 32f7adf633b9f99ad5089901bc7ebff57704aaa9 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
  3. Date: Thu, 3 Dec 2015 19:24:21 +0100
  4. Subject: [PATCH] net: qmi_wwan: support "raw IP" mode
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. QMI wwan devices have traditionally emulated ethernet devices
  9. by default. But they have always had the capability of operating
  10. without any L2 header at all, transmitting and receiving "raw"
  11. IP packets over the USB link. This firmware feature used to be
  12. configurable through the QMI management protocol.
  13. Traditionally there was no way to verify the firmware mode
  14. without attempting to change it. And the firmware would often
  15. disallow changes anyway, i.e. due to a session already being
  16. established. In some cases, this could be a hidden firmware
  17. internal session, completely outside host control. For these
  18. reasons, sticking with the "well known" default mode was safest.
  19. But newer generations of QMI hardware and firmware have moved
  20. towards defaulting to "raw IP" mode instead, followed by an
  21. increasing number of bugs in the already buggy "802.3" firmware
  22. implementation. At the same time, the QMI management protocol
  23. gained the ability to detect the current mode. This has enabled
  24. the userspace QMI management application to verify the current
  25. firmware mode without trying to modify it.
  26. Following this development, the latest QMI hardware and firmware
  27. (the MDM9x30 generation) has dropped support for "802.3" mode
  28. entirely. Support for "raw IP" framing in the driver is therefore
  29. necessary for these devices, and to a certain degree to work
  30. around problems with the previous generation,
  31. This patch adds support for "raw IP" framing for QMI devices,
  32. changing the netdev from an ethernet device to an ARPHRD_NONE
  33. p-t-p device when "raw IP" framing is enabled.
  34. The firmware setup is fully delegated to the QMI userspace
  35. management application, through simple tunneling of the QMI
  36. protocol. The driver will therefore not know which mode has been
  37. "negotiated" between firmware and userspace. Allowing userspace
  38. to inform the driver of the result through a sysfs switch is
  39. considered a better alternative than to change the well established
  40. clean delegation of firmware management to userspace.
  41. Signed-off-by: Bjørn Mork <bjorn@mork.no>
  42. Signed-off-by: David S. Miller <davem@davemloft.net>
  43. ---
  44. drivers/net/usb/qmi_wwan.c | 98 +++++++++++++++++++++++++++++++++++++++++++++-
  45. 1 file changed, 97 insertions(+), 1 deletion(-)
  46. --- a/drivers/net/usb/qmi_wwan.c
  47. +++ b/drivers/net/usb/qmi_wwan.c
  48. @@ -14,6 +14,7 @@
  49. #include <linux/netdevice.h>
  50. #include <linux/ethtool.h>
  51. #include <linux/etherdevice.h>
  52. +#include <linux/if_arp.h>
  53. #include <linux/mii.h>
  54. #include <linux/usb.h>
  55. #include <linux/usb/cdc.h>
  56. @@ -48,11 +49,93 @@
  57. struct qmi_wwan_state {
  58. struct usb_driver *subdriver;
  59. atomic_t pmcount;
  60. - unsigned long unused;
  61. + unsigned long flags;
  62. struct usb_interface *control;
  63. struct usb_interface *data;
  64. };
  65. +enum qmi_wwan_flags {
  66. + QMI_WWAN_FLAG_RAWIP = 1 << 0,
  67. +};
  68. +
  69. +static void qmi_wwan_netdev_setup(struct net_device *net)
  70. +{
  71. + struct usbnet *dev = netdev_priv(net);
  72. + struct qmi_wwan_state *info = (void *)&dev->data;
  73. +
  74. + if (info->flags & QMI_WWAN_FLAG_RAWIP) {
  75. + net->header_ops = NULL; /* No header */
  76. + net->type = ARPHRD_NONE;
  77. + net->hard_header_len = 0;
  78. + net->addr_len = 0;
  79. + net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
  80. + netdev_dbg(net, "mode: raw IP\n");
  81. + } else if (!net->header_ops) { /* don't bother if already set */
  82. + ether_setup(net);
  83. + netdev_dbg(net, "mode: Ethernet\n");
  84. + }
  85. +
  86. + /* recalculate buffers after changing hard_header_len */
  87. + usbnet_change_mtu(net, net->mtu);
  88. +}
  89. +
  90. +static ssize_t raw_ip_show(struct device *d, struct device_attribute *attr, char *buf)
  91. +{
  92. + struct usbnet *dev = netdev_priv(to_net_dev(d));
  93. + struct qmi_wwan_state *info = (void *)&dev->data;
  94. +
  95. + return sprintf(buf, "%c\n", info->flags & QMI_WWAN_FLAG_RAWIP ? 'Y' : 'N');
  96. +}
  97. +
  98. +static ssize_t raw_ip_store(struct device *d, struct device_attribute *attr, const char *buf, size_t len)
  99. +{
  100. + struct usbnet *dev = netdev_priv(to_net_dev(d));
  101. + struct qmi_wwan_state *info = (void *)&dev->data;
  102. + bool enable;
  103. + int err;
  104. +
  105. + if (strtobool(buf, &enable))
  106. + return -EINVAL;
  107. +
  108. + /* no change? */
  109. + if (enable == (info->flags & QMI_WWAN_FLAG_RAWIP))
  110. + return len;
  111. +
  112. + /* we don't want to modify a running netdev */
  113. + if (netif_running(dev->net)) {
  114. + netdev_err(dev->net, "Cannot change a running device\n");
  115. + return -EBUSY;
  116. + }
  117. +
  118. + /* let other drivers deny the change */
  119. + err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev->net);
  120. + err = notifier_to_errno(err);
  121. + if (err) {
  122. + netdev_err(dev->net, "Type change was refused\n");
  123. + return err;
  124. + }
  125. +
  126. + if (enable)
  127. + info->flags |= QMI_WWAN_FLAG_RAWIP;
  128. + else
  129. + info->flags &= ~QMI_WWAN_FLAG_RAWIP;
  130. + qmi_wwan_netdev_setup(dev->net);
  131. + call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev->net);
  132. + return len;
  133. +}
  134. +
  135. +static DEVICE_ATTR_RW(raw_ip);
  136. +
  137. +static struct attribute *qmi_wwan_sysfs_attrs[] = {
  138. + &dev_attr_raw_ip.attr,
  139. + NULL,
  140. +};
  141. +
  142. +static struct attribute_group qmi_wwan_sysfs_attr_group = {
  143. + .name = "qmi",
  144. + .attrs = qmi_wwan_sysfs_attrs,
  145. +};
  146. +
  147. /* default ethernet address used by the modem */
  148. static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3};
  149. @@ -80,6 +163,8 @@ static const u8 buggy_fw_addr[ETH_ALEN]
  150. */
  151. static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
  152. {
  153. + struct qmi_wwan_state *info = (void *)&dev->data;
  154. + bool rawip = info->flags & QMI_WWAN_FLAG_RAWIP;
  155. __be16 proto;
  156. /* This check is no longer done by usbnet */
  157. @@ -94,15 +179,25 @@ static int qmi_wwan_rx_fixup(struct usbn
  158. proto = htons(ETH_P_IPV6);
  159. break;
  160. case 0x00:
  161. + if (rawip)
  162. + return 0;
  163. if (is_multicast_ether_addr(skb->data))
  164. return 1;
  165. /* possibly bogus destination - rewrite just in case */
  166. skb_reset_mac_header(skb);
  167. goto fix_dest;
  168. default:
  169. + if (rawip)
  170. + return 0;
  171. /* pass along other packets without modifications */
  172. return 1;
  173. }
  174. + if (rawip) {
  175. + skb->dev = dev->net; /* normally set by eth_type_trans */
  176. + skb->protocol = proto;
  177. + return 1;
  178. + }
  179. +
  180. if (skb_headroom(skb) < ETH_HLEN)
  181. return 0;
  182. skb_push(skb, ETH_HLEN);
  183. @@ -294,6 +389,7 @@ static int qmi_wwan_bind(struct usbnet *
  184. dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */
  185. }
  186. dev->net->netdev_ops = &qmi_wwan_netdev_ops;
  187. + dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group;
  188. err:
  189. return status;
  190. }