1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Host Side support for RNDIS Networking Links
4 * Copyright (C) 2005 by David Brownell
5 */
6
7#ifndef	__LINUX_USB_RNDIS_HOST_H
8#define	__LINUX_USB_RNDIS_HOST_H
9
10#include <linux/rndis.h>
11
12/*
13 * CONTROL uses CDC "encapsulated commands" with funky notifications.
14 *  - control-out:  SEND_ENCAPSULATED
15 *  - interrupt-in:  RESPONSE_AVAILABLE
16 *  - control-in:  GET_ENCAPSULATED
17 *
18 * We'll try to ignore the RESPONSE_AVAILABLE notifications.
19 *
20 * REVISIT some RNDIS implementations seem to have curious issues still
21 * to be resolved.
22 */
23struct rndis_msg_hdr {
24	__le32	msg_type;			/* RNDIS_MSG_* */
25	__le32	msg_len;
26	/* followed by data that varies between messages */
27	__le32	request_id;
28	__le32	status;
29	/* ... and more */
30} __attribute__ ((packed));
31
32/* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
33#define	CONTROL_BUFFER_SIZE		1025
34
35/* RNDIS defines an (absurdly huge) 10 second control timeout,
36 * but ActiveSync seems to use a more usual 5 second timeout
37 * (which matches the USB 2.0 spec).
38 */
39#define	RNDIS_CONTROL_TIMEOUT_MS	(5 * 1000)
40
41struct rndis_data_hdr {
42	__le32	msg_type;		/* RNDIS_MSG_PACKET */
43	__le32	msg_len;		/* rndis_data_hdr + data_len + pad */
44	__le32	data_offset;		/* 36 -- right after header */
45	__le32	data_len;		/* ... real packet size */
46
47	__le32	oob_data_offset;	/* zero */
48	__le32	oob_data_len;		/* zero */
49	__le32	num_oob;		/* zero */
50	__le32	packet_data_offset;	/* zero */
51
52	__le32	packet_data_len;	/* zero */
53	__le32	vc_handle;		/* zero */
54	__le32	reserved;		/* zero */
55} __attribute__ ((packed));
56
57struct rndis_init {		/* OUT */
58	/* header and: */
59	__le32	msg_type;			/* RNDIS_MSG_INIT */
60	__le32	msg_len;			/* 24 */
61	__le32	request_id;
62	__le32	major_version;			/* of rndis (1.0) */
63	__le32	minor_version;
64	__le32	max_transfer_size;
65} __attribute__ ((packed));
66
67struct rndis_init_c {		/* IN */
68	/* header and: */
69	__le32	msg_type;			/* RNDIS_MSG_INIT_C */
70	__le32	msg_len;
71	__le32	request_id;
72	__le32	status;
73	__le32	major_version;			/* of rndis (1.0) */
74	__le32	minor_version;
75	__le32	device_flags;
76	__le32	medium;				/* zero == 802.3 */
77	__le32	max_packets_per_message;
78	__le32	max_transfer_size;
79	__le32	packet_alignment;		/* max 7; (1<<n) bytes */
80	__le32	af_list_offset;			/* zero */
81	__le32	af_list_size;			/* zero */
82} __attribute__ ((packed));
83
84struct rndis_halt {		/* OUT (no reply) */
85	/* header and: */
86	__le32	msg_type;			/* RNDIS_MSG_HALT */
87	__le32	msg_len;
88	__le32	request_id;
89} __attribute__ ((packed));
90
91struct rndis_query {		/* OUT */
92	/* header and: */
93	__le32	msg_type;			/* RNDIS_MSG_QUERY */
94	__le32	msg_len;
95	__le32	request_id;
96	__le32	oid;
97	__le32	len;
98	__le32	offset;
99/*?*/	__le32	handle;				/* zero */
100} __attribute__ ((packed));
101
102struct rndis_query_c {		/* IN */
103	/* header and: */
104	__le32	msg_type;			/* RNDIS_MSG_QUERY_C */
105	__le32	msg_len;
106	__le32	request_id;
107	__le32	status;
108	__le32	len;
109	__le32	offset;
110} __attribute__ ((packed));
111
112struct rndis_set {		/* OUT */
113	/* header and: */
114	__le32	msg_type;			/* RNDIS_MSG_SET */
115	__le32	msg_len;
116	__le32	request_id;
117	__le32	oid;
118	__le32	len;
119	__le32	offset;
120/*?*/	__le32	handle;				/* zero */
121} __attribute__ ((packed));
122
123struct rndis_set_c {		/* IN */
124	/* header and: */
125	__le32	msg_type;			/* RNDIS_MSG_SET_C */
126	__le32	msg_len;
127	__le32	request_id;
128	__le32	status;
129} __attribute__ ((packed));
130
131struct rndis_reset {		/* IN */
132	/* header and: */
133	__le32	msg_type;			/* RNDIS_MSG_RESET */
134	__le32	msg_len;
135	__le32	reserved;
136} __attribute__ ((packed));
137
138struct rndis_reset_c {		/* OUT */
139	/* header and: */
140	__le32	msg_type;			/* RNDIS_MSG_RESET_C */
141	__le32	msg_len;
142	__le32	status;
143	__le32	addressing_lost;
144} __attribute__ ((packed));
145
146struct rndis_indicate {		/* IN (unrequested) */
147	/* header and: */
148	__le32	msg_type;			/* RNDIS_MSG_INDICATE */
149	__le32	msg_len;
150	__le32	status;
151	__le32	length;
152	__le32	offset;
153/**/	__le32	diag_status;
154	__le32	error_offset;
155/**/	__le32	message;
156} __attribute__ ((packed));
157
158struct rndis_keepalive {	/* OUT (optionally IN) */
159	/* header and: */
160	__le32	msg_type;			/* RNDIS_MSG_KEEPALIVE */
161	__le32	msg_len;
162	__le32	request_id;
163} __attribute__ ((packed));
164
165struct rndis_keepalive_c {	/* IN (optionally OUT) */
166	/* header and: */
167	__le32	msg_type;			/* RNDIS_MSG_KEEPALIVE_C */
168	__le32	msg_len;
169	__le32	request_id;
170	__le32	status;
171} __attribute__ ((packed));
172
173/* default filter used with RNDIS devices */
174#define RNDIS_DEFAULT_FILTER ( \
175	RNDIS_PACKET_TYPE_DIRECTED | \
176	RNDIS_PACKET_TYPE_BROADCAST | \
177	RNDIS_PACKET_TYPE_ALL_MULTICAST | \
178	RNDIS_PACKET_TYPE_PROMISCUOUS)
179
180/* Flags to require specific physical medium type for generic_rndis_bind() */
181#define FLAG_RNDIS_PHYM_NOT_WIRELESS	0x0001
182#define FLAG_RNDIS_PHYM_WIRELESS	0x0002
183
184/* Flags for driver_info::data */
185#define RNDIS_DRIVER_DATA_POLL_STATUS	1	/* poll status before control */
186#define RNDIS_DRIVER_DATA_DST_MAC_FIXUP	2	/* device ignores configured MAC address */
187
188extern void rndis_status(struct usbnet *dev, struct urb *urb);
189extern int
190rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen);
191extern int
192generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags);
193extern void rndis_unbind(struct usbnet *dev, struct usb_interface *intf);
194extern int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb);
195extern struct sk_buff *
196rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags);
197
198#endif	/* __LINUX_USB_RNDIS_HOST_H */
199