xref: /linux/drivers/net/usb/rndis_host.c (revision 5b2fc499917e5897a13add780e181b4cef197072)
1*5b2fc499SJeff Garzik /*
2*5b2fc499SJeff Garzik  * Host Side support for RNDIS Networking Links
3*5b2fc499SJeff Garzik  * Copyright (C) 2005 by David Brownell
4*5b2fc499SJeff Garzik  *
5*5b2fc499SJeff Garzik  * This program is free software; you can redistribute it and/or modify
6*5b2fc499SJeff Garzik  * it under the terms of the GNU General Public License as published by
7*5b2fc499SJeff Garzik  * the Free Software Foundation; either version 2 of the License, or
8*5b2fc499SJeff Garzik  * (at your option) any later version.
9*5b2fc499SJeff Garzik  *
10*5b2fc499SJeff Garzik  * This program is distributed in the hope that it will be useful,
11*5b2fc499SJeff Garzik  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*5b2fc499SJeff Garzik  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*5b2fc499SJeff Garzik  * GNU General Public License for more details.
14*5b2fc499SJeff Garzik  *
15*5b2fc499SJeff Garzik  * You should have received a copy of the GNU General Public License
16*5b2fc499SJeff Garzik  * along with this program; if not, write to the Free Software
17*5b2fc499SJeff Garzik  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18*5b2fc499SJeff Garzik  */
19*5b2fc499SJeff Garzik 
20*5b2fc499SJeff Garzik // #define	DEBUG			// error path messages, extra info
21*5b2fc499SJeff Garzik // #define	VERBOSE			// more; success messages
22*5b2fc499SJeff Garzik 
23*5b2fc499SJeff Garzik #include <linux/module.h>
24*5b2fc499SJeff Garzik #include <linux/init.h>
25*5b2fc499SJeff Garzik #include <linux/netdevice.h>
26*5b2fc499SJeff Garzik #include <linux/etherdevice.h>
27*5b2fc499SJeff Garzik #include <linux/ethtool.h>
28*5b2fc499SJeff Garzik #include <linux/workqueue.h>
29*5b2fc499SJeff Garzik #include <linux/mii.h>
30*5b2fc499SJeff Garzik #include <linux/usb.h>
31*5b2fc499SJeff Garzik #include <linux/usb/cdc.h>
32*5b2fc499SJeff Garzik 
33*5b2fc499SJeff Garzik #include "usbnet.h"
34*5b2fc499SJeff Garzik 
35*5b2fc499SJeff Garzik 
36*5b2fc499SJeff Garzik /*
37*5b2fc499SJeff Garzik  * RNDIS is NDIS remoted over USB.  It's a MSFT variant of CDC ACM ... of
38*5b2fc499SJeff Garzik  * course ACM was intended for modems, not Ethernet links!  USB's standard
39*5b2fc499SJeff Garzik  * for Ethernet links is "CDC Ethernet", which is significantly simpler.
40*5b2fc499SJeff Garzik  *
41*5b2fc499SJeff Garzik  * NOTE that Microsoft's "RNDIS 1.0" specification is incomplete.  Issues
42*5b2fc499SJeff Garzik  * include:
43*5b2fc499SJeff Garzik  *    - Power management in particular relies on information that's scattered
44*5b2fc499SJeff Garzik  *	through other documentation, and which is incomplete or incorrect even
45*5b2fc499SJeff Garzik  *	there.
46*5b2fc499SJeff Garzik  *    - There are various undocumented protocol requirements, such as the
47*5b2fc499SJeff Garzik  *	need to send unused garbage in control-OUT messages.
48*5b2fc499SJeff Garzik  *    - In some cases, MS-Windows will emit undocumented requests; this
49*5b2fc499SJeff Garzik  *	matters more to peripheral implementations than host ones.
50*5b2fc499SJeff Garzik  *
51*5b2fc499SJeff Garzik  * Moreover there's a no-open-specs variant of RNDIS called "ActiveSync".
52*5b2fc499SJeff Garzik  *
53*5b2fc499SJeff Garzik  * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in
54*5b2fc499SJeff Garzik  * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and
55*5b2fc499SJeff Garzik  * currently rare) "Ethernet Emulation Model" (EEM).
56*5b2fc499SJeff Garzik  */
57*5b2fc499SJeff Garzik 
58*5b2fc499SJeff Garzik /*
59*5b2fc499SJeff Garzik  * CONTROL uses CDC "encapsulated commands" with funky notifications.
60*5b2fc499SJeff Garzik  *  - control-out:  SEND_ENCAPSULATED
61*5b2fc499SJeff Garzik  *  - interrupt-in:  RESPONSE_AVAILABLE
62*5b2fc499SJeff Garzik  *  - control-in:  GET_ENCAPSULATED
63*5b2fc499SJeff Garzik  *
64*5b2fc499SJeff Garzik  * We'll try to ignore the RESPONSE_AVAILABLE notifications.
65*5b2fc499SJeff Garzik  *
66*5b2fc499SJeff Garzik  * REVISIT some RNDIS implementations seem to have curious issues still
67*5b2fc499SJeff Garzik  * to be resolved.
68*5b2fc499SJeff Garzik  */
69*5b2fc499SJeff Garzik struct rndis_msg_hdr {
70*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_* */
71*5b2fc499SJeff Garzik 	__le32	msg_len;
72*5b2fc499SJeff Garzik 	// followed by data that varies between messages
73*5b2fc499SJeff Garzik 	__le32	request_id;
74*5b2fc499SJeff Garzik 	__le32	status;
75*5b2fc499SJeff Garzik 	// ... and more
76*5b2fc499SJeff Garzik } __attribute__ ((packed));
77*5b2fc499SJeff Garzik 
78*5b2fc499SJeff Garzik /* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */
79*5b2fc499SJeff Garzik #define	CONTROL_BUFFER_SIZE		1025
80*5b2fc499SJeff Garzik 
81*5b2fc499SJeff Garzik /* RNDIS defines an (absurdly huge) 10 second control timeout,
82*5b2fc499SJeff Garzik  * but ActiveSync seems to use a more usual 5 second timeout
83*5b2fc499SJeff Garzik  * (which matches the USB 2.0 spec).
84*5b2fc499SJeff Garzik  */
85*5b2fc499SJeff Garzik #define	RNDIS_CONTROL_TIMEOUT_MS	(5 * 1000)
86*5b2fc499SJeff Garzik 
87*5b2fc499SJeff Garzik 
88*5b2fc499SJeff Garzik #define ccpu2 __constant_cpu_to_le32
89*5b2fc499SJeff Garzik 
90*5b2fc499SJeff Garzik #define RNDIS_MSG_COMPLETION	ccpu2(0x80000000)
91*5b2fc499SJeff Garzik 
92*5b2fc499SJeff Garzik /* codes for "msg_type" field of rndis messages;
93*5b2fc499SJeff Garzik  * only the data channel uses packet messages (maybe batched);
94*5b2fc499SJeff Garzik  * everything else goes on the control channel.
95*5b2fc499SJeff Garzik  */
96*5b2fc499SJeff Garzik #define RNDIS_MSG_PACKET	ccpu2(0x00000001)	/* 1-N packets */
97*5b2fc499SJeff Garzik #define RNDIS_MSG_INIT		ccpu2(0x00000002)
98*5b2fc499SJeff Garzik #define RNDIS_MSG_INIT_C	(RNDIS_MSG_INIT|RNDIS_MSG_COMPLETION)
99*5b2fc499SJeff Garzik #define RNDIS_MSG_HALT		ccpu2(0x00000003)
100*5b2fc499SJeff Garzik #define RNDIS_MSG_QUERY		ccpu2(0x00000004)
101*5b2fc499SJeff Garzik #define RNDIS_MSG_QUERY_C	(RNDIS_MSG_QUERY|RNDIS_MSG_COMPLETION)
102*5b2fc499SJeff Garzik #define RNDIS_MSG_SET		ccpu2(0x00000005)
103*5b2fc499SJeff Garzik #define RNDIS_MSG_SET_C		(RNDIS_MSG_SET|RNDIS_MSG_COMPLETION)
104*5b2fc499SJeff Garzik #define RNDIS_MSG_RESET		ccpu2(0x00000006)
105*5b2fc499SJeff Garzik #define RNDIS_MSG_RESET_C	(RNDIS_MSG_RESET|RNDIS_MSG_COMPLETION)
106*5b2fc499SJeff Garzik #define RNDIS_MSG_INDICATE	ccpu2(0x00000007)
107*5b2fc499SJeff Garzik #define RNDIS_MSG_KEEPALIVE	ccpu2(0x00000008)
108*5b2fc499SJeff Garzik #define RNDIS_MSG_KEEPALIVE_C	(RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
109*5b2fc499SJeff Garzik 
110*5b2fc499SJeff Garzik /* codes for "status" field of completion messages */
111*5b2fc499SJeff Garzik #define	RNDIS_STATUS_SUCCESS		ccpu2(0x00000000)
112*5b2fc499SJeff Garzik #define	RNDIS_STATUS_FAILURE		ccpu2(0xc0000001)
113*5b2fc499SJeff Garzik #define	RNDIS_STATUS_INVALID_DATA	ccpu2(0xc0010015)
114*5b2fc499SJeff Garzik #define	RNDIS_STATUS_NOT_SUPPORTED	ccpu2(0xc00000bb)
115*5b2fc499SJeff Garzik #define	RNDIS_STATUS_MEDIA_CONNECT	ccpu2(0x4001000b)
116*5b2fc499SJeff Garzik #define	RNDIS_STATUS_MEDIA_DISCONNECT	ccpu2(0x4001000c)
117*5b2fc499SJeff Garzik 
118*5b2fc499SJeff Garzik 
119*5b2fc499SJeff Garzik struct rndis_data_hdr {
120*5b2fc499SJeff Garzik 	__le32	msg_type;		/* RNDIS_MSG_PACKET */
121*5b2fc499SJeff Garzik 	__le32	msg_len;		// rndis_data_hdr + data_len + pad
122*5b2fc499SJeff Garzik 	__le32	data_offset;		// 36 -- right after header
123*5b2fc499SJeff Garzik 	__le32	data_len;		// ... real packet size
124*5b2fc499SJeff Garzik 
125*5b2fc499SJeff Garzik 	__le32	oob_data_offset;	// zero
126*5b2fc499SJeff Garzik 	__le32	oob_data_len;		// zero
127*5b2fc499SJeff Garzik 	__le32	num_oob;		// zero
128*5b2fc499SJeff Garzik 	__le32	packet_data_offset;	// zero
129*5b2fc499SJeff Garzik 
130*5b2fc499SJeff Garzik 	__le32	packet_data_len;	// zero
131*5b2fc499SJeff Garzik 	__le32	vc_handle;		// zero
132*5b2fc499SJeff Garzik 	__le32	reserved;		// zero
133*5b2fc499SJeff Garzik } __attribute__ ((packed));
134*5b2fc499SJeff Garzik 
135*5b2fc499SJeff Garzik struct rndis_init {		/* OUT */
136*5b2fc499SJeff Garzik 	// header and:
137*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_INIT */
138*5b2fc499SJeff Garzik 	__le32	msg_len;			// 24
139*5b2fc499SJeff Garzik 	__le32	request_id;
140*5b2fc499SJeff Garzik 	__le32	major_version;			// of rndis (1.0)
141*5b2fc499SJeff Garzik 	__le32	minor_version;
142*5b2fc499SJeff Garzik 	__le32	max_transfer_size;
143*5b2fc499SJeff Garzik } __attribute__ ((packed));
144*5b2fc499SJeff Garzik 
145*5b2fc499SJeff Garzik struct rndis_init_c {		/* IN */
146*5b2fc499SJeff Garzik 	// header and:
147*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_INIT_C */
148*5b2fc499SJeff Garzik 	__le32	msg_len;
149*5b2fc499SJeff Garzik 	__le32	request_id;
150*5b2fc499SJeff Garzik 	__le32	status;
151*5b2fc499SJeff Garzik 	__le32	major_version;			// of rndis (1.0)
152*5b2fc499SJeff Garzik 	__le32	minor_version;
153*5b2fc499SJeff Garzik 	__le32	device_flags;
154*5b2fc499SJeff Garzik 	__le32	medium;				// zero == 802.3
155*5b2fc499SJeff Garzik 	__le32	max_packets_per_message;
156*5b2fc499SJeff Garzik 	__le32	max_transfer_size;
157*5b2fc499SJeff Garzik 	__le32	packet_alignment;		// max 7; (1<<n) bytes
158*5b2fc499SJeff Garzik 	__le32	af_list_offset;			// zero
159*5b2fc499SJeff Garzik 	__le32	af_list_size;			// zero
160*5b2fc499SJeff Garzik } __attribute__ ((packed));
161*5b2fc499SJeff Garzik 
162*5b2fc499SJeff Garzik struct rndis_halt {		/* OUT (no reply) */
163*5b2fc499SJeff Garzik 	// header and:
164*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_HALT */
165*5b2fc499SJeff Garzik 	__le32	msg_len;
166*5b2fc499SJeff Garzik 	__le32	request_id;
167*5b2fc499SJeff Garzik } __attribute__ ((packed));
168*5b2fc499SJeff Garzik 
169*5b2fc499SJeff Garzik struct rndis_query {		/* OUT */
170*5b2fc499SJeff Garzik 	// header and:
171*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_QUERY */
172*5b2fc499SJeff Garzik 	__le32	msg_len;
173*5b2fc499SJeff Garzik 	__le32	request_id;
174*5b2fc499SJeff Garzik 	__le32	oid;
175*5b2fc499SJeff Garzik 	__le32	len;
176*5b2fc499SJeff Garzik 	__le32	offset;
177*5b2fc499SJeff Garzik /*?*/	__le32	handle;				// zero
178*5b2fc499SJeff Garzik } __attribute__ ((packed));
179*5b2fc499SJeff Garzik 
180*5b2fc499SJeff Garzik struct rndis_query_c {		/* IN */
181*5b2fc499SJeff Garzik 	// header and:
182*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_QUERY_C */
183*5b2fc499SJeff Garzik 	__le32	msg_len;
184*5b2fc499SJeff Garzik 	__le32	request_id;
185*5b2fc499SJeff Garzik 	__le32	status;
186*5b2fc499SJeff Garzik 	__le32	len;
187*5b2fc499SJeff Garzik 	__le32	offset;
188*5b2fc499SJeff Garzik } __attribute__ ((packed));
189*5b2fc499SJeff Garzik 
190*5b2fc499SJeff Garzik struct rndis_set {		/* OUT */
191*5b2fc499SJeff Garzik 	// header and:
192*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_SET */
193*5b2fc499SJeff Garzik 	__le32	msg_len;
194*5b2fc499SJeff Garzik 	__le32	request_id;
195*5b2fc499SJeff Garzik 	__le32	oid;
196*5b2fc499SJeff Garzik 	__le32	len;
197*5b2fc499SJeff Garzik 	__le32	offset;
198*5b2fc499SJeff Garzik /*?*/	__le32	handle;				// zero
199*5b2fc499SJeff Garzik } __attribute__ ((packed));
200*5b2fc499SJeff Garzik 
201*5b2fc499SJeff Garzik struct rndis_set_c {		/* IN */
202*5b2fc499SJeff Garzik 	// header and:
203*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_SET_C */
204*5b2fc499SJeff Garzik 	__le32	msg_len;
205*5b2fc499SJeff Garzik 	__le32	request_id;
206*5b2fc499SJeff Garzik 	__le32	status;
207*5b2fc499SJeff Garzik } __attribute__ ((packed));
208*5b2fc499SJeff Garzik 
209*5b2fc499SJeff Garzik struct rndis_reset {		/* IN */
210*5b2fc499SJeff Garzik 	// header and:
211*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_RESET */
212*5b2fc499SJeff Garzik 	__le32	msg_len;
213*5b2fc499SJeff Garzik 	__le32	reserved;
214*5b2fc499SJeff Garzik } __attribute__ ((packed));
215*5b2fc499SJeff Garzik 
216*5b2fc499SJeff Garzik struct rndis_reset_c {		/* OUT */
217*5b2fc499SJeff Garzik 	// header and:
218*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_RESET_C */
219*5b2fc499SJeff Garzik 	__le32	msg_len;
220*5b2fc499SJeff Garzik 	__le32	status;
221*5b2fc499SJeff Garzik 	__le32	addressing_lost;
222*5b2fc499SJeff Garzik } __attribute__ ((packed));
223*5b2fc499SJeff Garzik 
224*5b2fc499SJeff Garzik struct rndis_indicate {		/* IN (unrequested) */
225*5b2fc499SJeff Garzik 	// header and:
226*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_INDICATE */
227*5b2fc499SJeff Garzik 	__le32	msg_len;
228*5b2fc499SJeff Garzik 	__le32	status;
229*5b2fc499SJeff Garzik 	__le32	length;
230*5b2fc499SJeff Garzik 	__le32	offset;
231*5b2fc499SJeff Garzik /**/	__le32	diag_status;
232*5b2fc499SJeff Garzik 	__le32	error_offset;
233*5b2fc499SJeff Garzik /**/	__le32	message;
234*5b2fc499SJeff Garzik } __attribute__ ((packed));
235*5b2fc499SJeff Garzik 
236*5b2fc499SJeff Garzik struct rndis_keepalive {	/* OUT (optionally IN) */
237*5b2fc499SJeff Garzik 	// header and:
238*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_KEEPALIVE */
239*5b2fc499SJeff Garzik 	__le32	msg_len;
240*5b2fc499SJeff Garzik 	__le32	request_id;
241*5b2fc499SJeff Garzik } __attribute__ ((packed));
242*5b2fc499SJeff Garzik 
243*5b2fc499SJeff Garzik struct rndis_keepalive_c {	/* IN (optionally OUT) */
244*5b2fc499SJeff Garzik 	// header and:
245*5b2fc499SJeff Garzik 	__le32	msg_type;			/* RNDIS_MSG_KEEPALIVE_C */
246*5b2fc499SJeff Garzik 	__le32	msg_len;
247*5b2fc499SJeff Garzik 	__le32	request_id;
248*5b2fc499SJeff Garzik 	__le32	status;
249*5b2fc499SJeff Garzik } __attribute__ ((packed));
250*5b2fc499SJeff Garzik 
251*5b2fc499SJeff Garzik /* NOTE:  about 30 OIDs are "mandatory" for peripherals to support ... and
252*5b2fc499SJeff Garzik  * there are gobs more that may optionally be supported.  We'll avoid as much
253*5b2fc499SJeff Garzik  * of that mess as possible.
254*5b2fc499SJeff Garzik  */
255*5b2fc499SJeff Garzik #define OID_802_3_PERMANENT_ADDRESS	ccpu2(0x01010101)
256*5b2fc499SJeff Garzik #define OID_GEN_MAXIMUM_FRAME_SIZE	ccpu2(0x00010106)
257*5b2fc499SJeff Garzik #define OID_GEN_CURRENT_PACKET_FILTER	ccpu2(0x0001010e)
258*5b2fc499SJeff Garzik 
259*5b2fc499SJeff Garzik /*
260*5b2fc499SJeff Garzik  * RNDIS notifications from device: command completion; "reverse"
261*5b2fc499SJeff Garzik  * keepalives; etc
262*5b2fc499SJeff Garzik  */
263*5b2fc499SJeff Garzik static void rndis_status(struct usbnet *dev, struct urb *urb)
264*5b2fc499SJeff Garzik {
265*5b2fc499SJeff Garzik 	devdbg(dev, "rndis status urb, len %d stat %d",
266*5b2fc499SJeff Garzik 		urb->actual_length, urb->status);
267*5b2fc499SJeff Garzik 	// FIXME for keepalives, respond immediately (asynchronously)
268*5b2fc499SJeff Garzik 	// if not an RNDIS status, do like cdc_status(dev,urb) does
269*5b2fc499SJeff Garzik }
270*5b2fc499SJeff Garzik 
271*5b2fc499SJeff Garzik /*
272*5b2fc499SJeff Garzik  * RPC done RNDIS-style.  Caller guarantees:
273*5b2fc499SJeff Garzik  * - message is properly byteswapped
274*5b2fc499SJeff Garzik  * - there's no other request pending
275*5b2fc499SJeff Garzik  * - buf can hold up to 1KB response (required by RNDIS spec)
276*5b2fc499SJeff Garzik  * On return, the first few entries are already byteswapped.
277*5b2fc499SJeff Garzik  *
278*5b2fc499SJeff Garzik  * Call context is likely probe(), before interface name is known,
279*5b2fc499SJeff Garzik  * which is why we won't try to use it in the diagnostics.
280*5b2fc499SJeff Garzik  */
281*5b2fc499SJeff Garzik static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
282*5b2fc499SJeff Garzik {
283*5b2fc499SJeff Garzik 	struct cdc_state	*info = (void *) &dev->data;
284*5b2fc499SJeff Garzik 	int			master_ifnum;
285*5b2fc499SJeff Garzik 	int			retval;
286*5b2fc499SJeff Garzik 	unsigned		count;
287*5b2fc499SJeff Garzik 	__le32			rsp;
288*5b2fc499SJeff Garzik 	u32			xid = 0, msg_len, request_id;
289*5b2fc499SJeff Garzik 
290*5b2fc499SJeff Garzik 	/* REVISIT when this gets called from contexts other than probe() or
291*5b2fc499SJeff Garzik 	 * disconnect(): either serialize, or dispatch responses on xid
292*5b2fc499SJeff Garzik 	 */
293*5b2fc499SJeff Garzik 
294*5b2fc499SJeff Garzik 	/* Issue the request; xid is unique, don't bother byteswapping it */
295*5b2fc499SJeff Garzik 	if (likely(buf->msg_type != RNDIS_MSG_HALT
296*5b2fc499SJeff Garzik 			&& buf->msg_type != RNDIS_MSG_RESET)) {
297*5b2fc499SJeff Garzik 		xid = dev->xid++;
298*5b2fc499SJeff Garzik 		if (!xid)
299*5b2fc499SJeff Garzik 			xid = dev->xid++;
300*5b2fc499SJeff Garzik 		buf->request_id = (__force __le32) xid;
301*5b2fc499SJeff Garzik 	}
302*5b2fc499SJeff Garzik 	master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber;
303*5b2fc499SJeff Garzik 	retval = usb_control_msg(dev->udev,
304*5b2fc499SJeff Garzik 		usb_sndctrlpipe(dev->udev, 0),
305*5b2fc499SJeff Garzik 		USB_CDC_SEND_ENCAPSULATED_COMMAND,
306*5b2fc499SJeff Garzik 		USB_TYPE_CLASS | USB_RECIP_INTERFACE,
307*5b2fc499SJeff Garzik 		0, master_ifnum,
308*5b2fc499SJeff Garzik 		buf, le32_to_cpu(buf->msg_len),
309*5b2fc499SJeff Garzik 		RNDIS_CONTROL_TIMEOUT_MS);
310*5b2fc499SJeff Garzik 	if (unlikely(retval < 0 || xid == 0))
311*5b2fc499SJeff Garzik 		return retval;
312*5b2fc499SJeff Garzik 
313*5b2fc499SJeff Garzik 	// FIXME Seems like some devices discard responses when
314*5b2fc499SJeff Garzik 	// we time out and cancel our "get response" requests...
315*5b2fc499SJeff Garzik 	// so, this is fragile.  Probably need to poll for status.
316*5b2fc499SJeff Garzik 
317*5b2fc499SJeff Garzik 	/* ignore status endpoint, just poll the control channel;
318*5b2fc499SJeff Garzik 	 * the request probably completed immediately
319*5b2fc499SJeff Garzik 	 */
320*5b2fc499SJeff Garzik 	rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
321*5b2fc499SJeff Garzik 	for (count = 0; count < 10; count++) {
322*5b2fc499SJeff Garzik 		memset(buf, 0, CONTROL_BUFFER_SIZE);
323*5b2fc499SJeff Garzik 		retval = usb_control_msg(dev->udev,
324*5b2fc499SJeff Garzik 			usb_rcvctrlpipe(dev->udev, 0),
325*5b2fc499SJeff Garzik 			USB_CDC_GET_ENCAPSULATED_RESPONSE,
326*5b2fc499SJeff Garzik 			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
327*5b2fc499SJeff Garzik 			0, master_ifnum,
328*5b2fc499SJeff Garzik 			buf, CONTROL_BUFFER_SIZE,
329*5b2fc499SJeff Garzik 			RNDIS_CONTROL_TIMEOUT_MS);
330*5b2fc499SJeff Garzik 		if (likely(retval >= 8)) {
331*5b2fc499SJeff Garzik 			msg_len = le32_to_cpu(buf->msg_len);
332*5b2fc499SJeff Garzik 			request_id = (__force u32) buf->request_id;
333*5b2fc499SJeff Garzik 			if (likely(buf->msg_type == rsp)) {
334*5b2fc499SJeff Garzik 				if (likely(request_id == xid)) {
335*5b2fc499SJeff Garzik 					if (unlikely(rsp == RNDIS_MSG_RESET_C))
336*5b2fc499SJeff Garzik 						return 0;
337*5b2fc499SJeff Garzik 					if (likely(RNDIS_STATUS_SUCCESS
338*5b2fc499SJeff Garzik 							== buf->status))
339*5b2fc499SJeff Garzik 						return 0;
340*5b2fc499SJeff Garzik 					dev_dbg(&info->control->dev,
341*5b2fc499SJeff Garzik 						"rndis reply status %08x\n",
342*5b2fc499SJeff Garzik 						le32_to_cpu(buf->status));
343*5b2fc499SJeff Garzik 					return -EL3RST;
344*5b2fc499SJeff Garzik 				}
345*5b2fc499SJeff Garzik 				dev_dbg(&info->control->dev,
346*5b2fc499SJeff Garzik 					"rndis reply id %d expected %d\n",
347*5b2fc499SJeff Garzik 					request_id, xid);
348*5b2fc499SJeff Garzik 				/* then likely retry */
349*5b2fc499SJeff Garzik 			} else switch (buf->msg_type) {
350*5b2fc499SJeff Garzik 			case RNDIS_MSG_INDICATE: {	/* fault */
351*5b2fc499SJeff Garzik 				// struct rndis_indicate *msg = (void *)buf;
352*5b2fc499SJeff Garzik 				dev_info(&info->control->dev,
353*5b2fc499SJeff Garzik 					"rndis fault indication\n");
354*5b2fc499SJeff Garzik 				}
355*5b2fc499SJeff Garzik 				break;
356*5b2fc499SJeff Garzik 			case RNDIS_MSG_KEEPALIVE: {	/* ping */
357*5b2fc499SJeff Garzik 				struct rndis_keepalive_c *msg = (void *)buf;
358*5b2fc499SJeff Garzik 
359*5b2fc499SJeff Garzik 				msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
360*5b2fc499SJeff Garzik 				msg->msg_len = ccpu2(sizeof *msg);
361*5b2fc499SJeff Garzik 				msg->status = RNDIS_STATUS_SUCCESS;
362*5b2fc499SJeff Garzik 				retval = usb_control_msg(dev->udev,
363*5b2fc499SJeff Garzik 					usb_sndctrlpipe(dev->udev, 0),
364*5b2fc499SJeff Garzik 					USB_CDC_SEND_ENCAPSULATED_COMMAND,
365*5b2fc499SJeff Garzik 					USB_TYPE_CLASS | USB_RECIP_INTERFACE,
366*5b2fc499SJeff Garzik 					0, master_ifnum,
367*5b2fc499SJeff Garzik 					msg, sizeof *msg,
368*5b2fc499SJeff Garzik 					RNDIS_CONTROL_TIMEOUT_MS);
369*5b2fc499SJeff Garzik 				if (unlikely(retval < 0))
370*5b2fc499SJeff Garzik 					dev_dbg(&info->control->dev,
371*5b2fc499SJeff Garzik 						"rndis keepalive err %d\n",
372*5b2fc499SJeff Garzik 						retval);
373*5b2fc499SJeff Garzik 				}
374*5b2fc499SJeff Garzik 				break;
375*5b2fc499SJeff Garzik 			default:
376*5b2fc499SJeff Garzik 				dev_dbg(&info->control->dev,
377*5b2fc499SJeff Garzik 					"unexpected rndis msg %08x len %d\n",
378*5b2fc499SJeff Garzik 					le32_to_cpu(buf->msg_type), msg_len);
379*5b2fc499SJeff Garzik 			}
380*5b2fc499SJeff Garzik 		} else {
381*5b2fc499SJeff Garzik 			/* device probably issued a protocol stall; ignore */
382*5b2fc499SJeff Garzik 			dev_dbg(&info->control->dev,
383*5b2fc499SJeff Garzik 				"rndis response error, code %d\n", retval);
384*5b2fc499SJeff Garzik 		}
385*5b2fc499SJeff Garzik 		msleep(2);
386*5b2fc499SJeff Garzik 	}
387*5b2fc499SJeff Garzik 	dev_dbg(&info->control->dev, "rndis response timeout\n");
388*5b2fc499SJeff Garzik 	return -ETIMEDOUT;
389*5b2fc499SJeff Garzik }
390*5b2fc499SJeff Garzik 
391*5b2fc499SJeff Garzik /*
392*5b2fc499SJeff Garzik  * rndis_query:
393*5b2fc499SJeff Garzik  *
394*5b2fc499SJeff Garzik  * Performs a query for @oid along with 0 or more bytes of payload as
395*5b2fc499SJeff Garzik  * specified by @in_len. If @reply_len is not set to -1 then the reply
396*5b2fc499SJeff Garzik  * length is checked against this value, resulting in an error if it
397*5b2fc499SJeff Garzik  * doesn't match.
398*5b2fc499SJeff Garzik  *
399*5b2fc499SJeff Garzik  * NOTE: Adding a payload exactly or greater than the size of the expected
400*5b2fc499SJeff Garzik  * response payload is an evident requirement MSFT added for ActiveSync.
401*5b2fc499SJeff Garzik  *
402*5b2fc499SJeff Garzik  * The only exception is for OIDs that return a variably sized response,
403*5b2fc499SJeff Garzik  * in which case no payload should be added.  This undocumented (and
404*5b2fc499SJeff Garzik  * nonsensical!) issue was found by sniffing protocol requests from the
405*5b2fc499SJeff Garzik  * ActiveSync 4.1 Windows driver.
406*5b2fc499SJeff Garzik  */
407*5b2fc499SJeff Garzik static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
408*5b2fc499SJeff Garzik 		void *buf, u32 oid, u32 in_len,
409*5b2fc499SJeff Garzik 		void **reply, int *reply_len)
410*5b2fc499SJeff Garzik {
411*5b2fc499SJeff Garzik 	int retval;
412*5b2fc499SJeff Garzik 	union {
413*5b2fc499SJeff Garzik 		void			*buf;
414*5b2fc499SJeff Garzik 		struct rndis_msg_hdr	*header;
415*5b2fc499SJeff Garzik 		struct rndis_query	*get;
416*5b2fc499SJeff Garzik 		struct rndis_query_c	*get_c;
417*5b2fc499SJeff Garzik 	} u;
418*5b2fc499SJeff Garzik 	u32 off, len;
419*5b2fc499SJeff Garzik 
420*5b2fc499SJeff Garzik 	u.buf = buf;
421*5b2fc499SJeff Garzik 
422*5b2fc499SJeff Garzik 	memset(u.get, 0, sizeof *u.get + in_len);
423*5b2fc499SJeff Garzik 	u.get->msg_type = RNDIS_MSG_QUERY;
424*5b2fc499SJeff Garzik 	u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len);
425*5b2fc499SJeff Garzik 	u.get->oid = oid;
426*5b2fc499SJeff Garzik 	u.get->len = cpu_to_le32(in_len);
427*5b2fc499SJeff Garzik 	u.get->offset = ccpu2(20);
428*5b2fc499SJeff Garzik 
429*5b2fc499SJeff Garzik 	retval = rndis_command(dev, u.header);
430*5b2fc499SJeff Garzik 	if (unlikely(retval < 0)) {
431*5b2fc499SJeff Garzik 		dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) failed, %d\n",
432*5b2fc499SJeff Garzik 				oid, retval);
433*5b2fc499SJeff Garzik 		return retval;
434*5b2fc499SJeff Garzik 	}
435*5b2fc499SJeff Garzik 
436*5b2fc499SJeff Garzik 	off = le32_to_cpu(u.get_c->offset);
437*5b2fc499SJeff Garzik 	len = le32_to_cpu(u.get_c->len);
438*5b2fc499SJeff Garzik 	if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
439*5b2fc499SJeff Garzik 		goto response_error;
440*5b2fc499SJeff Garzik 
441*5b2fc499SJeff Garzik 	if (*reply_len != -1 && len != *reply_len)
442*5b2fc499SJeff Garzik 		goto response_error;
443*5b2fc499SJeff Garzik 
444*5b2fc499SJeff Garzik 	*reply = (unsigned char *) &u.get_c->request_id + off;
445*5b2fc499SJeff Garzik 	*reply_len = len;
446*5b2fc499SJeff Garzik 
447*5b2fc499SJeff Garzik 	return retval;
448*5b2fc499SJeff Garzik 
449*5b2fc499SJeff Garzik response_error:
450*5b2fc499SJeff Garzik 	dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) "
451*5b2fc499SJeff Garzik 			"invalid response - off %d len %d\n",
452*5b2fc499SJeff Garzik 		oid, off, len);
453*5b2fc499SJeff Garzik 	return -EDOM;
454*5b2fc499SJeff Garzik }
455*5b2fc499SJeff Garzik 
456*5b2fc499SJeff Garzik static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
457*5b2fc499SJeff Garzik {
458*5b2fc499SJeff Garzik 	int			retval;
459*5b2fc499SJeff Garzik 	struct net_device	*net = dev->net;
460*5b2fc499SJeff Garzik 	struct cdc_state	*info = (void *) &dev->data;
461*5b2fc499SJeff Garzik 	union {
462*5b2fc499SJeff Garzik 		void			*buf;
463*5b2fc499SJeff Garzik 		struct rndis_msg_hdr	*header;
464*5b2fc499SJeff Garzik 		struct rndis_init	*init;
465*5b2fc499SJeff Garzik 		struct rndis_init_c	*init_c;
466*5b2fc499SJeff Garzik 		struct rndis_query	*get;
467*5b2fc499SJeff Garzik 		struct rndis_query_c	*get_c;
468*5b2fc499SJeff Garzik 		struct rndis_set	*set;
469*5b2fc499SJeff Garzik 		struct rndis_set_c	*set_c;
470*5b2fc499SJeff Garzik 	} u;
471*5b2fc499SJeff Garzik 	u32			tmp;
472*5b2fc499SJeff Garzik 	int			reply_len;
473*5b2fc499SJeff Garzik 	unsigned char		*bp;
474*5b2fc499SJeff Garzik 
475*5b2fc499SJeff Garzik 	/* we can't rely on i/o from stack working, or stack allocation */
476*5b2fc499SJeff Garzik 	u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
477*5b2fc499SJeff Garzik 	if (!u.buf)
478*5b2fc499SJeff Garzik 		return -ENOMEM;
479*5b2fc499SJeff Garzik 	retval = usbnet_generic_cdc_bind(dev, intf);
480*5b2fc499SJeff Garzik 	if (retval < 0)
481*5b2fc499SJeff Garzik 		goto fail;
482*5b2fc499SJeff Garzik 
483*5b2fc499SJeff Garzik 	u.init->msg_type = RNDIS_MSG_INIT;
484*5b2fc499SJeff Garzik 	u.init->msg_len = ccpu2(sizeof *u.init);
485*5b2fc499SJeff Garzik 	u.init->major_version = ccpu2(1);
486*5b2fc499SJeff Garzik 	u.init->minor_version = ccpu2(0);
487*5b2fc499SJeff Garzik 
488*5b2fc499SJeff Garzik 	/* max transfer (in spec) is 0x4000 at full speed, but for
489*5b2fc499SJeff Garzik 	 * TX we'll stick to one Ethernet packet plus RNDIS framing.
490*5b2fc499SJeff Garzik 	 * For RX we handle drivers that zero-pad to end-of-packet.
491*5b2fc499SJeff Garzik 	 * Don't let userspace change these settings.
492*5b2fc499SJeff Garzik 	 *
493*5b2fc499SJeff Garzik 	 * NOTE: there still seems to be wierdness here, as if we need
494*5b2fc499SJeff Garzik 	 * to do some more things to make sure WinCE targets accept this.
495*5b2fc499SJeff Garzik 	 * They default to jumbograms of 8KB or 16KB, which is absurd
496*5b2fc499SJeff Garzik 	 * for such low data rates and which is also more than Linux
497*5b2fc499SJeff Garzik 	 * can usually expect to allocate for SKB data...
498*5b2fc499SJeff Garzik 	 */
499*5b2fc499SJeff Garzik 	net->hard_header_len += sizeof (struct rndis_data_hdr);
500*5b2fc499SJeff Garzik 	dev->hard_mtu = net->mtu + net->hard_header_len;
501*5b2fc499SJeff Garzik 
502*5b2fc499SJeff Garzik 	dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1);
503*5b2fc499SJeff Garzik 	dev->rx_urb_size &= ~(dev->maxpacket - 1);
504*5b2fc499SJeff Garzik 	u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
505*5b2fc499SJeff Garzik 
506*5b2fc499SJeff Garzik 	net->change_mtu = NULL;
507*5b2fc499SJeff Garzik 	retval = rndis_command(dev, u.header);
508*5b2fc499SJeff Garzik 	if (unlikely(retval < 0)) {
509*5b2fc499SJeff Garzik 		/* it might not even be an RNDIS device!! */
510*5b2fc499SJeff Garzik 		dev_err(&intf->dev, "RNDIS init failed, %d\n", retval);
511*5b2fc499SJeff Garzik 		goto fail_and_release;
512*5b2fc499SJeff Garzik 	}
513*5b2fc499SJeff Garzik 	tmp = le32_to_cpu(u.init_c->max_transfer_size);
514*5b2fc499SJeff Garzik 	if (tmp < dev->hard_mtu) {
515*5b2fc499SJeff Garzik 		dev_err(&intf->dev,
516*5b2fc499SJeff Garzik 			"dev can't take %u byte packets (max %u)\n",
517*5b2fc499SJeff Garzik 			dev->hard_mtu, tmp);
518*5b2fc499SJeff Garzik 		goto fail_and_release;
519*5b2fc499SJeff Garzik 	}
520*5b2fc499SJeff Garzik 
521*5b2fc499SJeff Garzik 	/* REVISIT:  peripheral "alignment" request is ignored ... */
522*5b2fc499SJeff Garzik 	dev_dbg(&intf->dev,
523*5b2fc499SJeff Garzik 		"hard mtu %u (%u from dev), rx buflen %Zu, align %d\n",
524*5b2fc499SJeff Garzik 		dev->hard_mtu, tmp, dev->rx_urb_size,
525*5b2fc499SJeff Garzik 		1 << le32_to_cpu(u.init_c->packet_alignment));
526*5b2fc499SJeff Garzik 
527*5b2fc499SJeff Garzik 	/* Get designated host ethernet address */
528*5b2fc499SJeff Garzik 	reply_len = ETH_ALEN;
529*5b2fc499SJeff Garzik 	retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS,
530*5b2fc499SJeff Garzik 			48, (void **) &bp, &reply_len);
531*5b2fc499SJeff Garzik 	if (unlikely(retval< 0)) {
532*5b2fc499SJeff Garzik 		dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
533*5b2fc499SJeff Garzik 		goto fail_and_release;
534*5b2fc499SJeff Garzik 	}
535*5b2fc499SJeff Garzik 	memcpy(net->dev_addr, bp, ETH_ALEN);
536*5b2fc499SJeff Garzik 
537*5b2fc499SJeff Garzik 	/* set a nonzero filter to enable data transfers */
538*5b2fc499SJeff Garzik 	memset(u.set, 0, sizeof *u.set);
539*5b2fc499SJeff Garzik 	u.set->msg_type = RNDIS_MSG_SET;
540*5b2fc499SJeff Garzik 	u.set->msg_len = ccpu2(4 + sizeof *u.set);
541*5b2fc499SJeff Garzik 	u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
542*5b2fc499SJeff Garzik 	u.set->len = ccpu2(4);
543*5b2fc499SJeff Garzik 	u.set->offset = ccpu2((sizeof *u.set) - 8);
544*5b2fc499SJeff Garzik 	*(__le32 *)(u.buf + sizeof *u.set) = ccpu2(DEFAULT_FILTER);
545*5b2fc499SJeff Garzik 
546*5b2fc499SJeff Garzik 	retval = rndis_command(dev, u.header);
547*5b2fc499SJeff Garzik 	if (unlikely(retval < 0)) {
548*5b2fc499SJeff Garzik 		dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
549*5b2fc499SJeff Garzik 		goto fail_and_release;
550*5b2fc499SJeff Garzik 	}
551*5b2fc499SJeff Garzik 
552*5b2fc499SJeff Garzik 	retval = 0;
553*5b2fc499SJeff Garzik 
554*5b2fc499SJeff Garzik 	kfree(u.buf);
555*5b2fc499SJeff Garzik 	return retval;
556*5b2fc499SJeff Garzik 
557*5b2fc499SJeff Garzik fail_and_release:
558*5b2fc499SJeff Garzik 	usb_set_intfdata(info->data, NULL);
559*5b2fc499SJeff Garzik 	usb_driver_release_interface(driver_of(intf), info->data);
560*5b2fc499SJeff Garzik 	info->data = NULL;
561*5b2fc499SJeff Garzik fail:
562*5b2fc499SJeff Garzik 	kfree(u.buf);
563*5b2fc499SJeff Garzik 	return retval;
564*5b2fc499SJeff Garzik }
565*5b2fc499SJeff Garzik 
566*5b2fc499SJeff Garzik static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
567*5b2fc499SJeff Garzik {
568*5b2fc499SJeff Garzik 	struct rndis_halt	*halt;
569*5b2fc499SJeff Garzik 
570*5b2fc499SJeff Garzik 	/* try to clear any rndis state/activity (no i/o from stack!) */
571*5b2fc499SJeff Garzik 	halt = kzalloc(sizeof *halt, GFP_KERNEL);
572*5b2fc499SJeff Garzik 	if (halt) {
573*5b2fc499SJeff Garzik 		halt->msg_type = RNDIS_MSG_HALT;
574*5b2fc499SJeff Garzik 		halt->msg_len = ccpu2(sizeof *halt);
575*5b2fc499SJeff Garzik 		(void) rndis_command(dev, (void *)halt);
576*5b2fc499SJeff Garzik 		kfree(halt);
577*5b2fc499SJeff Garzik 	}
578*5b2fc499SJeff Garzik 
579*5b2fc499SJeff Garzik 	return usbnet_cdc_unbind(dev, intf);
580*5b2fc499SJeff Garzik }
581*5b2fc499SJeff Garzik 
582*5b2fc499SJeff Garzik /*
583*5b2fc499SJeff Garzik  * DATA -- host must not write zlps
584*5b2fc499SJeff Garzik  */
585*5b2fc499SJeff Garzik static int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
586*5b2fc499SJeff Garzik {
587*5b2fc499SJeff Garzik 	/* peripheral may have batched packets to us... */
588*5b2fc499SJeff Garzik 	while (likely(skb->len)) {
589*5b2fc499SJeff Garzik 		struct rndis_data_hdr	*hdr = (void *)skb->data;
590*5b2fc499SJeff Garzik 		struct sk_buff		*skb2;
591*5b2fc499SJeff Garzik 		u32			msg_len, data_offset, data_len;
592*5b2fc499SJeff Garzik 
593*5b2fc499SJeff Garzik 		msg_len = le32_to_cpu(hdr->msg_len);
594*5b2fc499SJeff Garzik 		data_offset = le32_to_cpu(hdr->data_offset);
595*5b2fc499SJeff Garzik 		data_len = le32_to_cpu(hdr->data_len);
596*5b2fc499SJeff Garzik 
597*5b2fc499SJeff Garzik 		/* don't choke if we see oob, per-packet data, etc */
598*5b2fc499SJeff Garzik 		if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET
599*5b2fc499SJeff Garzik 				|| skb->len < msg_len
600*5b2fc499SJeff Garzik 				|| (data_offset + data_len + 8) > msg_len)) {
601*5b2fc499SJeff Garzik 			dev->stats.rx_frame_errors++;
602*5b2fc499SJeff Garzik 			devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d",
603*5b2fc499SJeff Garzik 				le32_to_cpu(hdr->msg_type),
604*5b2fc499SJeff Garzik 				msg_len, data_offset, data_len, skb->len);
605*5b2fc499SJeff Garzik 			return 0;
606*5b2fc499SJeff Garzik 		}
607*5b2fc499SJeff Garzik 		skb_pull(skb, 8 + data_offset);
608*5b2fc499SJeff Garzik 
609*5b2fc499SJeff Garzik 		/* at most one packet left? */
610*5b2fc499SJeff Garzik 		if (likely((data_len - skb->len) <= sizeof *hdr)) {
611*5b2fc499SJeff Garzik 			skb_trim(skb, data_len);
612*5b2fc499SJeff Garzik 			break;
613*5b2fc499SJeff Garzik 		}
614*5b2fc499SJeff Garzik 
615*5b2fc499SJeff Garzik 		/* try to return all the packets in the batch */
616*5b2fc499SJeff Garzik 		skb2 = skb_clone(skb, GFP_ATOMIC);
617*5b2fc499SJeff Garzik 		if (unlikely(!skb2))
618*5b2fc499SJeff Garzik 			break;
619*5b2fc499SJeff Garzik 		skb_pull(skb, msg_len - sizeof *hdr);
620*5b2fc499SJeff Garzik 		skb_trim(skb2, data_len);
621*5b2fc499SJeff Garzik 		usbnet_skb_return(dev, skb2);
622*5b2fc499SJeff Garzik 	}
623*5b2fc499SJeff Garzik 
624*5b2fc499SJeff Garzik 	/* caller will usbnet_skb_return the remaining packet */
625*5b2fc499SJeff Garzik 	return 1;
626*5b2fc499SJeff Garzik }
627*5b2fc499SJeff Garzik 
628*5b2fc499SJeff Garzik static struct sk_buff *
629*5b2fc499SJeff Garzik rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
630*5b2fc499SJeff Garzik {
631*5b2fc499SJeff Garzik 	struct rndis_data_hdr	*hdr;
632*5b2fc499SJeff Garzik 	struct sk_buff		*skb2;
633*5b2fc499SJeff Garzik 	unsigned		len = skb->len;
634*5b2fc499SJeff Garzik 
635*5b2fc499SJeff Garzik 	if (likely(!skb_cloned(skb))) {
636*5b2fc499SJeff Garzik 		int	room = skb_headroom(skb);
637*5b2fc499SJeff Garzik 
638*5b2fc499SJeff Garzik 		/* enough head room as-is? */
639*5b2fc499SJeff Garzik 		if (unlikely((sizeof *hdr) <= room))
640*5b2fc499SJeff Garzik 			goto fill;
641*5b2fc499SJeff Garzik 
642*5b2fc499SJeff Garzik 		/* enough room, but needs to be readjusted? */
643*5b2fc499SJeff Garzik 		room += skb_tailroom(skb);
644*5b2fc499SJeff Garzik 		if (likely((sizeof *hdr) <= room)) {
645*5b2fc499SJeff Garzik 			skb->data = memmove(skb->head + sizeof *hdr,
646*5b2fc499SJeff Garzik 					    skb->data, len);
647*5b2fc499SJeff Garzik 			skb_set_tail_pointer(skb, len);
648*5b2fc499SJeff Garzik 			goto fill;
649*5b2fc499SJeff Garzik 		}
650*5b2fc499SJeff Garzik 	}
651*5b2fc499SJeff Garzik 
652*5b2fc499SJeff Garzik 	/* create a new skb, with the correct size (and tailpad) */
653*5b2fc499SJeff Garzik 	skb2 = skb_copy_expand(skb, sizeof *hdr, 1, flags);
654*5b2fc499SJeff Garzik 	dev_kfree_skb_any(skb);
655*5b2fc499SJeff Garzik 	if (unlikely(!skb2))
656*5b2fc499SJeff Garzik 		return skb2;
657*5b2fc499SJeff Garzik 	skb = skb2;
658*5b2fc499SJeff Garzik 
659*5b2fc499SJeff Garzik 	/* fill out the RNDIS header.  we won't bother trying to batch
660*5b2fc499SJeff Garzik 	 * packets; Linux minimizes wasted bandwidth through tx queues.
661*5b2fc499SJeff Garzik 	 */
662*5b2fc499SJeff Garzik fill:
663*5b2fc499SJeff Garzik 	hdr = (void *) __skb_push(skb, sizeof *hdr);
664*5b2fc499SJeff Garzik 	memset(hdr, 0, sizeof *hdr);
665*5b2fc499SJeff Garzik 	hdr->msg_type = RNDIS_MSG_PACKET;
666*5b2fc499SJeff Garzik 	hdr->msg_len = cpu_to_le32(skb->len);
667*5b2fc499SJeff Garzik 	hdr->data_offset = ccpu2(sizeof(*hdr) - 8);
668*5b2fc499SJeff Garzik 	hdr->data_len = cpu_to_le32(len);
669*5b2fc499SJeff Garzik 
670*5b2fc499SJeff Garzik 	/* FIXME make the last packet always be short ... */
671*5b2fc499SJeff Garzik 	return skb;
672*5b2fc499SJeff Garzik }
673*5b2fc499SJeff Garzik 
674*5b2fc499SJeff Garzik 
675*5b2fc499SJeff Garzik static const struct driver_info	rndis_info = {
676*5b2fc499SJeff Garzik 	.description =	"RNDIS device",
677*5b2fc499SJeff Garzik 	.flags =	FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT,
678*5b2fc499SJeff Garzik 	.bind =		rndis_bind,
679*5b2fc499SJeff Garzik 	.unbind =	rndis_unbind,
680*5b2fc499SJeff Garzik 	.status =	rndis_status,
681*5b2fc499SJeff Garzik 	.rx_fixup =	rndis_rx_fixup,
682*5b2fc499SJeff Garzik 	.tx_fixup =	rndis_tx_fixup,
683*5b2fc499SJeff Garzik };
684*5b2fc499SJeff Garzik 
685*5b2fc499SJeff Garzik #undef ccpu2
686*5b2fc499SJeff Garzik 
687*5b2fc499SJeff Garzik 
688*5b2fc499SJeff Garzik /*-------------------------------------------------------------------------*/
689*5b2fc499SJeff Garzik 
690*5b2fc499SJeff Garzik static const struct usb_device_id	products [] = {
691*5b2fc499SJeff Garzik {
692*5b2fc499SJeff Garzik 	/* RNDIS is MSFT's un-official variant of CDC ACM */
693*5b2fc499SJeff Garzik 	USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
694*5b2fc499SJeff Garzik 	.driver_info = (unsigned long) &rndis_info,
695*5b2fc499SJeff Garzik }, {
696*5b2fc499SJeff Garzik 	/* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
697*5b2fc499SJeff Garzik 	USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
698*5b2fc499SJeff Garzik 	.driver_info = (unsigned long) &rndis_info,
699*5b2fc499SJeff Garzik },
700*5b2fc499SJeff Garzik 	{ },		// END
701*5b2fc499SJeff Garzik };
702*5b2fc499SJeff Garzik MODULE_DEVICE_TABLE(usb, products);
703*5b2fc499SJeff Garzik 
704*5b2fc499SJeff Garzik static struct usb_driver rndis_driver = {
705*5b2fc499SJeff Garzik 	.name =		"rndis_host",
706*5b2fc499SJeff Garzik 	.id_table =	products,
707*5b2fc499SJeff Garzik 	.probe =	usbnet_probe,
708*5b2fc499SJeff Garzik 	.disconnect =	usbnet_disconnect,
709*5b2fc499SJeff Garzik 	.suspend =	usbnet_suspend,
710*5b2fc499SJeff Garzik 	.resume =	usbnet_resume,
711*5b2fc499SJeff Garzik };
712*5b2fc499SJeff Garzik 
713*5b2fc499SJeff Garzik static int __init rndis_init(void)
714*5b2fc499SJeff Garzik {
715*5b2fc499SJeff Garzik 	return usb_register(&rndis_driver);
716*5b2fc499SJeff Garzik }
717*5b2fc499SJeff Garzik module_init(rndis_init);
718*5b2fc499SJeff Garzik 
719*5b2fc499SJeff Garzik static void __exit rndis_exit(void)
720*5b2fc499SJeff Garzik {
721*5b2fc499SJeff Garzik 	usb_deregister(&rndis_driver);
722*5b2fc499SJeff Garzik }
723*5b2fc499SJeff Garzik module_exit(rndis_exit);
724*5b2fc499SJeff Garzik 
725*5b2fc499SJeff Garzik MODULE_AUTHOR("David Brownell");
726*5b2fc499SJeff Garzik MODULE_DESCRIPTION("USB Host side RNDIS driver");
727*5b2fc499SJeff Garzik MODULE_LICENSE("GPL");
728