Skip to content

Commit 9f651ca

Browse files
bmorkdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a82c7ce commit 9f651ca

File tree

1 file changed

+35
-23
lines changed

1 file changed

+35
-23
lines changed

drivers/net/usb/cdc_mbim.c

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,27 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
149149
/* mapping VLANs to MBIM sessions:
150150
* no tag => IPS session <0>
151151
* 1 - 255 => IPS session <vlanid>
152-
* 256 - 4095 => unsupported, drop
152+
* 256 - 511 => DSS session <vlanid - 256>
153+
* 512 - 4095 => unsupported, drop
153154
*/
154155
vlan_get_tag(skb, &tci);
155156

156157
switch (tci & 0x0f00) {
157158
case 0x0000: /* VLAN ID 0 - 255 */
159+
/* verify that datagram is IPv4 or IPv6 */
160+
skb_reset_mac_header(skb);
161+
switch (eth_hdr(skb)->h_proto) {
162+
case htons(ETH_P_IP):
163+
case htons(ETH_P_IPV6):
164+
break;
165+
default:
166+
goto error;
167+
}
168+
c = (u8 *)&sign;
169+
c[3] = tci;
170+
break;
171+
case 0x0100: /* VLAN ID 256 - 511 */
172+
sign = cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN);
158173
c = (u8 *)&sign;
159174
c[3] = tci;
160175
break;
@@ -163,16 +178,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
163178
"unsupported tci=0x%04x\n", tci);
164179
goto error;
165180
}
166-
167-
skb_reset_mac_header(skb);
168-
switch (eth_hdr(skb)->h_proto) {
169-
case htons(ETH_P_IP):
170-
case htons(ETH_P_IPV6):
171-
skb_pull(skb, ETH_HLEN);
172-
break;
173-
default:
174-
goto error;
175-
}
181+
skb_pull(skb, ETH_HLEN);
176182
}
177183

178184
spin_lock_bh(&ctx->mtx);
@@ -189,21 +195,23 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
189195

190196
static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_t len, u16 tci)
191197
{
192-
__be16 proto;
198+
__be16 proto = htons(ETH_P_802_3);
193199
struct sk_buff *skb = NULL;
194200

195-
if (len < sizeof(struct iphdr))
196-
goto err;
201+
if (tci < 256) { /* IPS session? */
202+
if (len < sizeof(struct iphdr))
203+
goto err;
197204

198-
switch (*buf & 0xf0) {
199-
case 0x40:
200-
proto = htons(ETH_P_IP);
201-
break;
202-
case 0x60:
203-
proto = htons(ETH_P_IPV6);
204-
break;
205-
default:
206-
goto err;
205+
switch (*buf & 0xf0) {
206+
case 0x40:
207+
proto = htons(ETH_P_IP);
208+
break;
209+
case 0x60:
210+
proto = htons(ETH_P_IPV6);
211+
break;
212+
default:
213+
goto err;
214+
}
207215
}
208216

209217
skb = netdev_alloc_skb_ip_align(dev->net, len + ETH_HLEN);
@@ -259,6 +267,10 @@ static int cdc_mbim_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
259267
c = (u8 *)&ndp16->dwSignature;
260268
tci = c[3];
261269
break;
270+
case cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN):
271+
c = (u8 *)&ndp16->dwSignature;
272+
tci = c[3] + 256;
273+
break;
262274
default:
263275
netif_dbg(dev, rx_err, dev->net,
264276
"unsupported NDP signature <0x%08x>\n",

0 commit comments

Comments
 (0)