netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Bjørn Mork" <bjorn-yOkvZcmFvRU@public.gmane.org>
To: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	"Oliver Neukum" <oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org>,
	"Greg Kroah-Hartman"
	<gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>,
	"Alexey Orishko"
	<alexey.orishko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	"Greg Suarez"
	<gpsuarez2512-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	"Fangxiaozhi (Franko)"
	<fangxiaozhi-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>,
	"Dan Williams" <dcbw-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	"Aleksander Morgado"
	<aleksander-bhGbAngMcJvQT0dZR+AlfA@public.gmane.org>,
	"Bjørn Mork" <bjorn-yOkvZcmFvRU@public.gmane.org>
Subject: [PATCH v2 net-next 12/13] net: cdc_ncm: map MBIM IPS SessionID to VLAN ID
Date: Mon, 22 Oct 2012 22:56:39 +0200	[thread overview]
Message-ID: <1350939400-27209-13-git-send-email-bjorn@mork.no> (raw)
In-Reply-To: <1350939400-27209-1-git-send-email-bjorn-yOkvZcmFvRU@public.gmane.org>

MBIM devices can support up to 256 independent IP Streams.
The main network device will only handle SessionID 0. Mapping
SessionIDs 1 to 255 to VLANs using the SessionID as VLAN ID
allow userspace to use these streams with traditional tools
like vconfig.

Signed-off-by: Bjørn Mork <bjorn-yOkvZcmFvRU@public.gmane.org>
---
 drivers/net/usb/cdc_mbim.c |   51 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 8 deletions(-)

diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 2f21139..45f5f50 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
+#include <linux/if_vlan.h>
 #include <linux/ip.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
@@ -107,6 +108,9 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
 
 	/* MBIM cannot do ARP */
 	dev->net->flags |= IFF_NOARP;
+
+	/* no need to put the VLAN tci in the packet headers */
+	dev->net->features |= NETIF_F_HW_VLAN_TX;
 err:
 	return ret;
 }
@@ -131,6 +135,9 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
 	struct sk_buff *skb_out;
 	struct cdc_mbim_state *info = (void *)&dev->data;
 	struct cdc_ncm_ctx *ctx = info->ctx;
+	__le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN);
+	u16 tci = 0;
+	u8 *c;
 
 	if (!ctx)
 		goto error;
@@ -139,6 +146,24 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
 		if (skb->len <= sizeof(ETH_HLEN))
 			goto error;
 
+		/* mapping VLANs to MBIM sessions:
+		 *   no tag     => IPS session <0>
+		 *   1 - 255    => IPS session <vlanid>
+		 *   256 - 4095 => unsupported, drop
+		 */
+		vlan_get_tag(skb, &tci);
+
+		switch (tci & 0x0f00) {
+		case 0x0000: /* VLAN ID 0 - 255 */
+			c = (u8 *)&sign;
+			c[3] = tci;
+			break;
+		default:
+			netif_err(dev, tx_err, dev->net,
+				  "unsupported tci=0x%04x\n", tci);
+			goto error;
+		}
+
 		skb_reset_mac_header(skb);
 		switch (eth_hdr(skb)->h_proto) {
 		case htons(ETH_P_IP):
@@ -151,7 +176,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
 	}
 
 	spin_lock_bh(&ctx->mtx);
-	skb_out = cdc_ncm_fill_tx_frame(ctx, skb, cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN));
+	skb_out = cdc_ncm_fill_tx_frame(ctx, skb, sign);
 	spin_unlock_bh(&ctx->mtx);
 	return skb_out;
 
@@ -162,11 +187,14 @@ error:
 	return NULL;
 }
 
-static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_t len)
+static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_t len, u16 tci)
 {
 	__be16 proto;
 	struct sk_buff *skb = NULL;
 
+	if (len < sizeof(struct iphdr))
+		goto err;
+
 	switch (*buf & 0xf0) {
 	case 0x40:
 		proto = htons(ETH_P_IP);
@@ -191,6 +219,10 @@ static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_
 
 	/* add datagram */
 	memcpy(skb_put(skb, len), buf, len);
+
+	/* map MBIM session to VLAN */
+	if (tci)
+		vlan_put_tag(skb, tci);
 err:
 	return skb;
 }
@@ -198,7 +230,8 @@ err:
 static int cdc_mbim_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
 {
 	struct sk_buff *skb;
-	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+	struct cdc_mbim_state *info = (void *)&dev->data;
+	struct cdc_ncm_ctx *ctx = info->ctx;
 	int len;
 	int nframes;
 	int x;
@@ -207,6 +240,8 @@ static int cdc_mbim_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
 	struct usb_cdc_ncm_dpe16 *dpe16;
 	int ndpoffset;
 	int loopcount = 50; /* arbitrary max preventing infinite loop */
+	u8 *c;
+	u16 tci;
 
 	ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in);
 	if (ndpoffset < 0)
@@ -219,9 +254,10 @@ next_ndp:
 
 	ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset);
 
-	/* only supporting IPS Session #0 for now */
-	switch (ndp16->dwSignature) {
+	switch (ndp16->dwSignature & cpu_to_le32(0x00ffffff)) {
 	case cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN):
+		c = (u8 *)&ndp16->dwSignature;
+		tci = c[3];
 		break;
 	default:
 		netif_dbg(dev, rx_err, dev->net,
@@ -247,8 +283,7 @@ next_ndp:
 		}
 
 		/* sanity checking */
-		if (((offset + len) > skb_in->len) || (len > ctx->rx_max) ||
-		    (len < sizeof(struct iphdr))) {
+		if (((offset + len) > skb_in->len) || (len > ctx->rx_max)) {
 			netif_dbg(dev, rx_err, dev->net,
 				  "invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n",
 				  x, offset, len, skb_in);
@@ -256,7 +291,7 @@ next_ndp:
 				goto err_ndp;
 			break;
 		} else {
-			skb = cdc_mbim_process_dgram(dev, skb_in->data + offset, len);
+			skb = cdc_mbim_process_dgram(dev, skb_in->data + offset, len, tci);
 			if (!skb)
 				goto error;
 			usbnet_skb_return(dev, skb);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2012-10-22 20:56 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-22 20:56 [PATCH v2 net-next 00/13] Adding a USB CDC MBIM driver Bjørn Mork
     [not found] ` <1350939400-27209-1-git-send-email-bjorn-yOkvZcmFvRU@public.gmane.org>
2012-10-22 20:56   ` [PATCH v2 net-next 01/13] net: cdc_ncm: workaround NTB input size firmware bug Bjørn Mork
2012-10-22 20:56   ` [PATCH v2 net-next 04/13] net: cdc_ncm: refactor bind preparing for MBIM support Bjørn Mork
2012-10-22 20:56   ` [PATCH v2 net-next 06/13] net: cdc_ncm: splitting rx_fixup for code reuse Bjørn Mork
2012-10-22 20:56   ` [PATCH v2 net-next 09/13] net: cdc_mbim: adding MBIM driver Bjørn Mork
2012-10-22 20:56   ` Bjørn Mork [this message]
2012-10-22 20:56 ` [PATCH v2 net-next 02/13] USB: cdc: add MBIM constants and structures Bjørn Mork
2012-10-22 20:56 ` [PATCH v2 net-next 03/13] net: cdc_ncm: adding MBIM support to ncm_setup Bjørn Mork
2012-10-22 20:56 ` [PATCH v2 net-next 05/13] net: cdc_ncm: process chained NDPs Bjørn Mork
2012-10-22 20:56 ` [PATCH v2 net-next 07/13] net: cdc_ncm: refactoring for tx multiplexing Bjørn Mork
2012-10-22 20:56 ` [PATCH v2 net-next 08/13] net: cdc_ncm: export shared symbols and definitions Bjørn Mork
2012-10-22 20:56 ` [PATCH v2 net-next 10/13] net: cdc_mbim: build the MBIM driver Bjørn Mork
2012-10-22 20:56 ` [PATCH v2 net-next 11/13] net: cdc_ncm: do not bind to NCM compatible MBIM devices Bjørn Mork
2012-10-22 20:56 ` [PATCH v2 net-next 13/13] net: cdc_mbim: Device Service Stream support Bjørn Mork
2012-10-23  6:41 ` [PATCH v2 net-next 00/13] Adding a USB CDC MBIM driver David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1350939400-27209-13-git-send-email-bjorn@mork.no \
    --to=bjorn-yokvzcmfvru@public.gmane.org \
    --cc=aleksander-bhGbAngMcJvQT0dZR+AlfA@public.gmane.org \
    --cc=alexey.orishko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=dcbw-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=fangxiaozhi-hv44wF8Li93QT0dZR+AlfA@public.gmane.org \
    --cc=gpsuarez2512-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org \
    --cc=linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).