[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <9c4aa5531548bf4a2e8b060b724a341476780b5d.camel@redhat.com>
Date: Mon, 25 Jan 2021 09:53:50 -0600
From: Dan Williams <dcbw@...hat.com>
To: Subash Abhinov Kasiviswanathan <subashab@...eaurora.org>,
davem@...emloft.net, kuba@...nel.org, netdev@...r.kernel.org,
stranche@...eaurora.org, aleksander@...ksander.es,
dnlplm@...il.com, bjorn@...k.no, stephan@...hold.net,
ejcaruso@...gle.com, andrewlassalle@...gle.com
Subject: Re: [PATCH net-next v2] net: qmi_wwan: Add pass through mode
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 <
> subashab@...eaurora.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);
Powered by blists - more mailing lists