diff options
author | Bjørn Mork <bjorn@mork.no> | 2012-10-22 10:56:40 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-10-23 02:40:11 -0400 |
commit | 9f651cace30c42e27e726a92f35e4edc55f1ec08 (patch) | |
tree | 36a1b04226c4c8a925d09a91bd35337108744ca4 /drivers | |
parent | a82c7ce5bc5be4d0cf8004d1f2ee362f9748c922 (diff) |
net: cdc_mbim: Device Service Stream support
MBIM devices can support up to 256 generic streams called
Device Service Streams (DSS). The MBIM spec says
The format of the Device Service Stream payload depends
on the device service (as identified by the corresponding
UUID) that is used when opening the data stream.
Example use cases are serial AT command interfaces and NMEA
data streams. We cannot make any assumptions about these
device services.
Adding support for Device Service Stream by extending
the MBIM session to VLAN mapping scheme, allocating
VLAN IDs 256 to 511 for DSS, using the DSS SessionID
as the lower 8bit of the VLAN ID.
Using a netdev for DSS keeps the device framing intact and
allows userspace to do whatever it want with the streams.
For example, exporting an AT command interface using DSS
session #0 to a PTY for use with a terminal application like
minicom:
vconfig add wwan0 256
ip link set dev wwan0 up
ip link set dev wwan0.256 up
socat INTERFACE:wwan0.256,type=2 PTY:,echo=0,link=/tmp/modem
Device configuration must be done using MBIM control commands
over the /dev/cdc-wdmx device. The userspace management
application should coordinate host VLAN configuration and the
device MBIM configuration using the device capabilities to
find out if it needs to set up PTY mappings etc.
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/usb/cdc_mbim.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index 45f5f50f8f26..42f51c71ec1f 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c @@ -149,12 +149,27 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb /* mapping VLANs to MBIM sessions: * no tag => IPS session <0> * 1 - 255 => IPS session <vlanid> - * 256 - 4095 => unsupported, drop + * 256 - 511 => DSS session <vlanid - 256> + * 512 - 4095 => unsupported, drop */ vlan_get_tag(skb, &tci); switch (tci & 0x0f00) { case 0x0000: /* VLAN ID 0 - 255 */ + /* verify that datagram is IPv4 or IPv6 */ + skb_reset_mac_header(skb); + switch (eth_hdr(skb)->h_proto) { + case htons(ETH_P_IP): + case htons(ETH_P_IPV6): + break; + default: + goto error; + } + c = (u8 *)&sign; + c[3] = tci; + break; + case 0x0100: /* VLAN ID 256 - 511 */ + sign = cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN); c = (u8 *)&sign; c[3] = tci; break; @@ -163,16 +178,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb "unsupported tci=0x%04x\n", tci); goto error; } - - skb_reset_mac_header(skb); - switch (eth_hdr(skb)->h_proto) { - case htons(ETH_P_IP): - case htons(ETH_P_IPV6): - skb_pull(skb, ETH_HLEN); - break; - default: - goto error; - } + skb_pull(skb, ETH_HLEN); } spin_lock_bh(&ctx->mtx); @@ -189,21 +195,23 @@ error: static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_t len, u16 tci) { - __be16 proto; + __be16 proto = htons(ETH_P_802_3); struct sk_buff *skb = NULL; - if (len < sizeof(struct iphdr)) - goto err; + if (tci < 256) { /* IPS session? */ + if (len < sizeof(struct iphdr)) + goto err; - switch (*buf & 0xf0) { - case 0x40: - proto = htons(ETH_P_IP); - break; - case 0x60: - proto = htons(ETH_P_IPV6); - break; - default: - goto err; + switch (*buf & 0xf0) { + case 0x40: + proto = htons(ETH_P_IP); + break; + case 0x60: + proto = htons(ETH_P_IPV6); + break; + default: + goto err; + } } skb = netdev_alloc_skb_ip_align(dev->net, len + ETH_HLEN); @@ -259,6 +267,10 @@ next_ndp: c = (u8 *)&ndp16->dwSignature; tci = c[3]; break; + case cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN): + c = (u8 *)&ndp16->dwSignature; + tci = c[3] + 256; + break; default: netif_dbg(dev, rx_err, dev->net, "unsupported NDP signature <0x%08x>\n", |