On Mon, 2021-01-25 at 00:33 -0700, Subash Abhinov Kasiviswanathan wrote: > Pass through mode is to allow packets in MAP format to be passed > on to the stack. rmnet driver can be used to process and demultiplex > these packets. > > Pass through mode can be enabled when the device is in raw ip mode > only. > Conversely, raw ip mode cannot be disabled when pass through mode is > enabled. > > Userspace can use pass through mode in conjunction with rmnet driver > through the following steps- > > 1. Enable raw ip mode on qmi_wwan device > 2. Enable pass through mode on qmi_wwan device > 3. Create a rmnet device with qmi_wwan device as real device using > netlink
This option is module-wide, right? eg, if there are multiple qmi_wwan-driven devices on the system, *all* of them must use MAP + passthrough, or none of them can, right? There are users that run 2+ devices on the same system, and different cards. I'm not sure I would assume that all can/would run in the same mode, unfortunately. Dan > Signed-off-by: Subash Abhinov Kasiviswanathan < > subas...@codeaurora.org> > --- > v1->v2: Update commit text and fix the following comments from Bjorn- > Remove locking as no netdev state change is requried since all the > configuration is already done in raw_ip_store. > Check the inverse relationship between raw_ip mode and pass_through > mode. > pass_through_mode just sets/resets the flag now. > raw_ip check is not needed when queueing pass_through mode packets as > that is enforced already during the mode configuration. > > drivers/net/usb/qmi_wwan.c | 58 > ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 58 insertions(+) > > diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c > index 7ea113f5..e58a80a 100644 > --- a/drivers/net/usb/qmi_wwan.c > +++ b/drivers/net/usb/qmi_wwan.c > @@ -57,6 +57,7 @@ struct qmi_wwan_state { > enum qmi_wwan_flags { > QMI_WWAN_FLAG_RAWIP = 1 << 0, > QMI_WWAN_FLAG_MUX = 1 << 1, > + QMI_WWAN_FLAG_PASS_THROUGH = 1 << 2, > }; > > enum qmi_wwan_quirks { > @@ -326,6 +327,13 @@ static ssize_t raw_ip_store(struct device > *d, struct device_attribute *attr, co > if (enable == (info->flags & QMI_WWAN_FLAG_RAWIP)) > return len; > > + /* ip mode cannot be cleared when pass through mode is set */ > + if (!enable && (info->flags & QMI_WWAN_FLAG_PASS_THROUGH)) { > + netdev_err(dev->net, > + "Cannot clear ip mode on pass through > device\n"); > + return -EINVAL; > + } > + > if (!rtnl_trylock()) > return restart_syscall(); > > @@ -456,14 +464,59 @@ static ssize_t del_mux_store(struct device > *d, struct device_attribute *attr, c > return ret; > } > > +static ssize_t pass_through_show(struct device *d, > + struct device_attribute *attr, char > *buf) > +{ > + struct usbnet *dev = netdev_priv(to_net_dev(d)); > + struct qmi_wwan_state *info; > + > + info = (void *)&dev->data; > + return sprintf(buf, "%c\n", > + info->flags & QMI_WWAN_FLAG_PASS_THROUGH ? 'Y' : > 'N'); > +} > + > +static ssize_t pass_through_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; > + bool enable; > + > + if (strtobool(buf, &enable)) > + return -EINVAL; > + > + info = (void *)&dev->data; > + > + /* no change? */ > + if (enable == (info->flags & QMI_WWAN_FLAG_PASS_THROUGH)) > + return len; > + > + /* pass through mode can be set for raw ip devices only */ > + if (!(info->flags & QMI_WWAN_FLAG_RAWIP)) { > + netdev_err(dev->net, > + "Cannot set pass through mode on non ip > device\n"); > + return -EINVAL; > + } > + > + if (enable) > + info->flags |= QMI_WWAN_FLAG_PASS_THROUGH; > + else > + info->flags &= ~QMI_WWAN_FLAG_PASS_THROUGH; > + > + return len; > +} > + > static DEVICE_ATTR_RW(raw_ip); > static DEVICE_ATTR_RW(add_mux); > static DEVICE_ATTR_RW(del_mux); > +static DEVICE_ATTR_RW(pass_through); > > static struct attribute *qmi_wwan_sysfs_attrs[] = { > &dev_attr_raw_ip.attr, > &dev_attr_add_mux.attr, > &dev_attr_del_mux.attr, > + &dev_attr_pass_through.attr, > NULL, > }; > > @@ -510,6 +563,11 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, > struct sk_buff *skb) > if (info->flags & QMI_WWAN_FLAG_MUX) > return qmimux_rx_fixup(dev, skb); > > + if (info->flags & QMI_WWAN_FLAG_PASS_THROUGH) { > + skb->protocol = htons(ETH_P_MAP); > + return (netif_rx(skb) == NET_RX_SUCCESS); > + } > + > switch (skb->data[0] & 0xf0) { > case 0x40: > proto = htons(ETH_P_IP);