xref: /openbmc/u-boot/drivers/usb/gadget/rndis.c (revision c0dcece7)
1 /*
2  * RNDIS MSG parser
3  *
4  * Authors:	Benedikt Spranger, Pengutronix
5  *		Robert Schwebel, Pengutronix
6  *
7  *              This program is free software; you can redistribute it and/or
8  *              modify it under the terms of the GNU General Public License
9  *              version 2, as published by the Free Software Foundation.
10  *
11  *		This software was originally developed in conformance with
12  *		Microsoft's Remote NDIS Specification License Agreement.
13  *
14  * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
15  *		Fixed message length bug in init_response
16  *
17  * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
18  *		Fixed rndis_rm_hdr length bug.
19  *
20  * Copyright (C) 2004 by David Brownell
21  *		updates to merge with Linux 2.6, better match RNDIS spec
22  */
23 
24 #include <common.h>
25 #include <net.h>
26 #include <malloc.h>
27 #include <linux/types.h>
28 #include <linux/list.h>
29 #include <linux/netdevice.h>
30 
31 #include <asm/byteorder.h>
32 #include <asm/unaligned.h>
33 #include <asm/errno.h>
34 
35 #undef	RNDIS_PM
36 #undef	RNDIS_WAKEUP
37 #undef	VERBOSE
38 
39 #include "rndis.h"
40 
41 #define ETH_ALEN	6		/* Octets in one ethernet addr	 */
42 #define ETH_HLEN	14		/* Total octets in header.	 */
43 #define ETH_ZLEN	60		/* Min. octets in frame sans FCS */
44 #define ETH_DATA_LEN	1500		/* Max. octets in payload	 */
45 #define ETH_FRAME_LEN	PKTSIZE_ALIGN	/* Max. octets in frame sans FCS */
46 #define ETH_FCS_LEN	4		/* Octets in the FCS		 */
47 #define ENOTSUPP        524     /* Operation is not supported */
48 
49 
50 /*
51  * The driver for your USB chip needs to support ep0 OUT to work with
52  * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
53  *
54  * Windows hosts need an INF file like Documentation/usb/linux.inf
55  * and will be happier if you provide the host_addr module parameter.
56  */
57 
58 #define RNDIS_MAX_CONFIGS	1
59 
60 static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS];
61 
62 /* Driver Version */
63 static const __le32 rndis_driver_version = __constant_cpu_to_le32(1);
64 
65 /* Function Prototypes */
66 static rndis_resp_t *rndis_add_response(int configNr, u32 length);
67 
68 
69 /* supported OIDs */
70 static const u32 oid_supported_list[] = {
71 	/* the general stuff */
72 	OID_GEN_SUPPORTED_LIST,
73 	OID_GEN_HARDWARE_STATUS,
74 	OID_GEN_MEDIA_SUPPORTED,
75 	OID_GEN_MEDIA_IN_USE,
76 	OID_GEN_MAXIMUM_FRAME_SIZE,
77 	OID_GEN_LINK_SPEED,
78 	OID_GEN_TRANSMIT_BLOCK_SIZE,
79 	OID_GEN_RECEIVE_BLOCK_SIZE,
80 	OID_GEN_VENDOR_ID,
81 	OID_GEN_VENDOR_DESCRIPTION,
82 	OID_GEN_VENDOR_DRIVER_VERSION,
83 	OID_GEN_CURRENT_PACKET_FILTER,
84 	OID_GEN_MAXIMUM_TOTAL_SIZE,
85 	OID_GEN_MEDIA_CONNECT_STATUS,
86 	OID_GEN_PHYSICAL_MEDIUM,
87 #if 0
88 	OID_GEN_RNDIS_CONFIG_PARAMETER,
89 #endif
90 
91 	/* the statistical stuff */
92 	OID_GEN_XMIT_OK,
93 	OID_GEN_RCV_OK,
94 	OID_GEN_XMIT_ERROR,
95 	OID_GEN_RCV_ERROR,
96 	OID_GEN_RCV_NO_BUFFER,
97 #ifdef	RNDIS_OPTIONAL_STATS
98 	OID_GEN_DIRECTED_BYTES_XMIT,
99 	OID_GEN_DIRECTED_FRAMES_XMIT,
100 	OID_GEN_MULTICAST_BYTES_XMIT,
101 	OID_GEN_MULTICAST_FRAMES_XMIT,
102 	OID_GEN_BROADCAST_BYTES_XMIT,
103 	OID_GEN_BROADCAST_FRAMES_XMIT,
104 	OID_GEN_DIRECTED_BYTES_RCV,
105 	OID_GEN_DIRECTED_FRAMES_RCV,
106 	OID_GEN_MULTICAST_BYTES_RCV,
107 	OID_GEN_MULTICAST_FRAMES_RCV,
108 	OID_GEN_BROADCAST_BYTES_RCV,
109 	OID_GEN_BROADCAST_FRAMES_RCV,
110 	OID_GEN_RCV_CRC_ERROR,
111 	OID_GEN_TRANSMIT_QUEUE_LENGTH,
112 #endif	/* RNDIS_OPTIONAL_STATS */
113 
114 	/* mandatory 802.3 */
115 	/* the general stuff */
116 	OID_802_3_PERMANENT_ADDRESS,
117 	OID_802_3_CURRENT_ADDRESS,
118 	OID_802_3_MULTICAST_LIST,
119 	OID_802_3_MAC_OPTIONS,
120 	OID_802_3_MAXIMUM_LIST_SIZE,
121 
122 	/* the statistical stuff */
123 	OID_802_3_RCV_ERROR_ALIGNMENT,
124 	OID_802_3_XMIT_ONE_COLLISION,
125 	OID_802_3_XMIT_MORE_COLLISIONS,
126 #ifdef	RNDIS_OPTIONAL_STATS
127 	OID_802_3_XMIT_DEFERRED,
128 	OID_802_3_XMIT_MAX_COLLISIONS,
129 	OID_802_3_RCV_OVERRUN,
130 	OID_802_3_XMIT_UNDERRUN,
131 	OID_802_3_XMIT_HEARTBEAT_FAILURE,
132 	OID_802_3_XMIT_TIMES_CRS_LOST,
133 	OID_802_3_XMIT_LATE_COLLISIONS,
134 #endif	/* RNDIS_OPTIONAL_STATS */
135 
136 #ifdef	RNDIS_PM
137 	/* PM and wakeup are mandatory for USB: */
138 
139 	/* power management */
140 	OID_PNP_CAPABILITIES,
141 	OID_PNP_QUERY_POWER,
142 	OID_PNP_SET_POWER,
143 
144 #ifdef	RNDIS_WAKEUP
145 	/* wake up host */
146 	OID_PNP_ENABLE_WAKE_UP,
147 	OID_PNP_ADD_WAKE_UP_PATTERN,
148 	OID_PNP_REMOVE_WAKE_UP_PATTERN,
149 #endif	/* RNDIS_WAKEUP */
150 #endif	/* RNDIS_PM */
151 };
152 
153 
154 /* NDIS Functions */
155 static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf,
156 				unsigned buf_len, rndis_resp_t *r)
157 {
158 	int				retval = -ENOTSUPP;
159 	u32				length = 4;	/* usually */
160 	__le32				*outbuf;
161 	int				i, count;
162 	rndis_query_cmplt_type		*resp;
163 	rndis_params			*params;
164 
165 	if (!r)
166 		return -ENOMEM;
167 	resp = (rndis_query_cmplt_type *) r->buf;
168 
169 	if (!resp)
170 		return -ENOMEM;
171 
172 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
173 	if (buf_len) {
174 		debug("query OID %08x value, len %d:\n", OID, buf_len);
175 		for (i = 0; i < buf_len; i += 16) {
176 			debug("%03d: %08x %08x %08x %08x\n", i,
177 				get_unaligned_le32(&buf[i]),
178 				get_unaligned_le32(&buf[i + 4]),
179 				get_unaligned_le32(&buf[i + 8]),
180 				get_unaligned_le32(&buf[i + 12]));
181 		}
182 	}
183 #endif
184 
185 	/* response goes here, right after the header */
186 	outbuf = (__le32 *) &resp[1];
187 	resp->InformationBufferOffset = __constant_cpu_to_le32(16);
188 
189 	params = &rndis_per_dev_params[configNr];
190 	switch (OID) {
191 
192 	/* general oids (table 4-1) */
193 
194 	/* mandatory */
195 	case OID_GEN_SUPPORTED_LIST:
196 		debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
197 		length = sizeof(oid_supported_list);
198 		count  = length / sizeof(u32);
199 		for (i = 0; i < count; i++)
200 			outbuf[i] = cpu_to_le32(oid_supported_list[i]);
201 		retval = 0;
202 		break;
203 
204 	/* mandatory */
205 	case OID_GEN_HARDWARE_STATUS:
206 		debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
207 		/*
208 		 * Bogus question!
209 		 * Hardware must be ready to receive high level protocols.
210 		 * BTW:
211 		 * reddite ergo quae sunt Caesaris Caesari
212 		 * et quae sunt Dei Deo!
213 		 */
214 		*outbuf = __constant_cpu_to_le32(0);
215 		retval = 0;
216 		break;
217 
218 	/* mandatory */
219 	case OID_GEN_MEDIA_SUPPORTED:
220 		debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
221 		*outbuf = cpu_to_le32(params->medium);
222 		retval = 0;
223 		break;
224 
225 	/* mandatory */
226 	case OID_GEN_MEDIA_IN_USE:
227 		debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
228 		/* one medium, one transport... (maybe you do it better) */
229 		*outbuf = cpu_to_le32(params->medium);
230 		retval = 0;
231 		break;
232 
233 	/* mandatory */
234 	case OID_GEN_MAXIMUM_FRAME_SIZE:
235 		debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
236 		if (params->dev) {
237 			*outbuf = cpu_to_le32(params->mtu);
238 			retval = 0;
239 		}
240 		break;
241 
242 	/* mandatory */
243 	case OID_GEN_LINK_SPEED:
244 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
245 		debug("%s: OID_GEN_LINK_SPEED\n", __func__);
246 #endif
247 		if (params->media_state == NDIS_MEDIA_STATE_DISCONNECTED)
248 			*outbuf = __constant_cpu_to_le32(0);
249 		else
250 			*outbuf = cpu_to_le32(params->speed);
251 		retval = 0;
252 		break;
253 
254 	/* mandatory */
255 	case OID_GEN_TRANSMIT_BLOCK_SIZE:
256 		debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
257 		if (params->dev) {
258 			*outbuf = cpu_to_le32(params->mtu);
259 			retval = 0;
260 		}
261 		break;
262 
263 	/* mandatory */
264 	case OID_GEN_RECEIVE_BLOCK_SIZE:
265 		debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
266 		if (params->dev) {
267 			*outbuf = cpu_to_le32(params->mtu);
268 			retval = 0;
269 		}
270 		break;
271 
272 	/* mandatory */
273 	case OID_GEN_VENDOR_ID:
274 		debug("%s: OID_GEN_VENDOR_ID\n", __func__);
275 		*outbuf = cpu_to_le32(params->vendorID);
276 		retval = 0;
277 		break;
278 
279 	/* mandatory */
280 	case OID_GEN_VENDOR_DESCRIPTION:
281 		debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
282 		length = strlen(params->vendorDescr);
283 		memcpy(outbuf, params->vendorDescr, length);
284 		retval = 0;
285 		break;
286 
287 	case OID_GEN_VENDOR_DRIVER_VERSION:
288 		debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
289 		/* Created as LE */
290 		*outbuf = rndis_driver_version;
291 		retval = 0;
292 		break;
293 
294 	/* mandatory */
295 	case OID_GEN_CURRENT_PACKET_FILTER:
296 		debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
297 		*outbuf = cpu_to_le32(*params->filter);
298 		retval = 0;
299 		break;
300 
301 	/* mandatory */
302 	case OID_GEN_MAXIMUM_TOTAL_SIZE:
303 		debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
304 		*outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
305 		retval = 0;
306 		break;
307 
308 	/* mandatory */
309 	case OID_GEN_MEDIA_CONNECT_STATUS:
310 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
311 		debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
312 #endif
313 		*outbuf = cpu_to_le32(params->media_state);
314 		retval = 0;
315 		break;
316 
317 	case OID_GEN_PHYSICAL_MEDIUM:
318 		debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
319 		*outbuf = __constant_cpu_to_le32(0);
320 		retval = 0;
321 		break;
322 
323 	/*
324 	 * The RNDIS specification is incomplete/wrong.   Some versions
325 	 * of MS-Windows expect OIDs that aren't specified there.  Other
326 	 * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
327 	 */
328 	case OID_GEN_MAC_OPTIONS:		/* from WinME */
329 		debug("%s: OID_GEN_MAC_OPTIONS\n", __func__);
330 		*outbuf = __constant_cpu_to_le32(
331 				  NDIS_MAC_OPTION_RECEIVE_SERIALIZED
332 				| NDIS_MAC_OPTION_FULL_DUPLEX);
333 		retval = 0;
334 		break;
335 
336 	/* statistics OIDs (table 4-2) */
337 
338 	/* mandatory */
339 	case OID_GEN_XMIT_OK:
340 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
341 		debug("%s: OID_GEN_XMIT_OK\n", __func__);
342 #endif
343 		if (params->stats) {
344 			*outbuf = cpu_to_le32(
345 					params->stats->tx_packets -
346 					params->stats->tx_errors -
347 					params->stats->tx_dropped);
348 			retval = 0;
349 		}
350 		break;
351 
352 	/* mandatory */
353 	case OID_GEN_RCV_OK:
354 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
355 		debug("%s: OID_GEN_RCV_OK\n", __func__);
356 #endif
357 		if (params->stats) {
358 			*outbuf = cpu_to_le32(
359 					params->stats->rx_packets -
360 					params->stats->rx_errors -
361 					params->stats->rx_dropped);
362 			retval = 0;
363 		}
364 		break;
365 
366 	/* mandatory */
367 	case OID_GEN_XMIT_ERROR:
368 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
369 		debug("%s: OID_GEN_XMIT_ERROR\n", __func__);
370 #endif
371 		if (params->stats) {
372 			*outbuf = cpu_to_le32(params->stats->tx_errors);
373 			retval = 0;
374 		}
375 		break;
376 
377 	/* mandatory */
378 	case OID_GEN_RCV_ERROR:
379 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
380 		debug("%s: OID_GEN_RCV_ERROR\n", __func__);
381 #endif
382 		if (params->stats) {
383 			*outbuf = cpu_to_le32(params->stats->rx_errors);
384 			retval = 0;
385 		}
386 		break;
387 
388 	/* mandatory */
389 	case OID_GEN_RCV_NO_BUFFER:
390 		debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
391 		if (params->stats) {
392 			*outbuf = cpu_to_le32(params->stats->rx_dropped);
393 			retval = 0;
394 		}
395 		break;
396 
397 #ifdef	RNDIS_OPTIONAL_STATS
398 	case OID_GEN_DIRECTED_BYTES_XMIT:
399 		debug("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __func__);
400 		/*
401 		 * Aunt Tilly's size of shoes
402 		 * minus antarctica count of penguins
403 		 * divided by weight of Alpha Centauri
404 		 */
405 		if (params->stats) {
406 			*outbuf = cpu_to_le32(
407 					(params->stats->tx_packets -
408 					 params->stats->tx_errors -
409 					 params->stats->tx_dropped)
410 					* 123);
411 			retval = 0;
412 		}
413 		break;
414 
415 	case OID_GEN_DIRECTED_FRAMES_XMIT:
416 		debug("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __func__);
417 		/* dito */
418 		if (params->stats) {
419 			*outbuf = cpu_to_le32(
420 					(params->stats->tx_packets -
421 					 params->stats->tx_errors -
422 					 params->stats->tx_dropped)
423 					/ 123);
424 			retval = 0;
425 		}
426 		break;
427 
428 	case OID_GEN_MULTICAST_BYTES_XMIT:
429 		debug("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __func__);
430 		if (params->stats) {
431 			*outbuf = cpu_to_le32(params->stats->multicast * 1234);
432 			retval = 0;
433 		}
434 		break;
435 
436 	case OID_GEN_MULTICAST_FRAMES_XMIT:
437 		debug("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __func__);
438 		if (params->stats) {
439 			*outbuf = cpu_to_le32(params->stats->multicast);
440 			retval = 0;
441 		}
442 		break;
443 
444 	case OID_GEN_BROADCAST_BYTES_XMIT:
445 		debug("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __func__);
446 		if (params->stats) {
447 			*outbuf = cpu_to_le32(params->stats->tx_packets/42*255);
448 			retval = 0;
449 		}
450 		break;
451 
452 	case OID_GEN_BROADCAST_FRAMES_XMIT:
453 		debug("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __func__);
454 		if (params->stats) {
455 			*outbuf = cpu_to_le32(params->stats->tx_packets / 42);
456 			retval = 0;
457 		}
458 		break;
459 
460 	case OID_GEN_DIRECTED_BYTES_RCV:
461 		debug("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __func__);
462 		*outbuf = __constant_cpu_to_le32(0);
463 		retval = 0;
464 		break;
465 
466 	case OID_GEN_DIRECTED_FRAMES_RCV:
467 		debug("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __func__);
468 		*outbuf = __constant_cpu_to_le32(0);
469 		retval = 0;
470 		break;
471 
472 	case OID_GEN_MULTICAST_BYTES_RCV:
473 		debug("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __func__);
474 		if (params->stats) {
475 			*outbuf = cpu_to_le32(params->stats->multicast * 1111);
476 			retval = 0;
477 		}
478 		break;
479 
480 	case OID_GEN_MULTICAST_FRAMES_RCV:
481 		debug("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __func__);
482 		if (params->stats) {
483 			*outbuf = cpu_to_le32(params->stats->multicast);
484 			retval = 0;
485 		}
486 		break;
487 
488 	case OID_GEN_BROADCAST_BYTES_RCV:
489 		debug("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __func__);
490 		if (params->stats) {
491 			*outbuf = cpu_to_le32(params->stats->rx_packets/42*255);
492 			retval = 0;
493 		}
494 		break;
495 
496 	case OID_GEN_BROADCAST_FRAMES_RCV:
497 		debug("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __func__);
498 		if (params->stats) {
499 			*outbuf = cpu_to_le32(params->stats->rx_packets / 42);
500 			retval = 0;
501 		}
502 		break;
503 
504 	case OID_GEN_RCV_CRC_ERROR:
505 		debug("%s: OID_GEN_RCV_CRC_ERROR\n", __func__);
506 		if (params->stats) {
507 			*outbuf = cpu_to_le32(params->stats->rx_crc_errors);
508 			retval = 0;
509 		}
510 		break;
511 
512 	case OID_GEN_TRANSMIT_QUEUE_LENGTH:
513 		debug("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __func__);
514 		*outbuf = __constant_cpu_to_le32(0);
515 		retval = 0;
516 		break;
517 #endif	/* RNDIS_OPTIONAL_STATS */
518 
519 	/* ieee802.3 OIDs (table 4-3) */
520 
521 	/* mandatory */
522 	case OID_802_3_PERMANENT_ADDRESS:
523 		debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
524 		if (params->dev) {
525 			length = ETH_ALEN;
526 			memcpy(outbuf, params->host_mac, length);
527 			retval = 0;
528 		}
529 		break;
530 
531 	/* mandatory */
532 	case OID_802_3_CURRENT_ADDRESS:
533 		debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
534 		if (params->dev) {
535 			length = ETH_ALEN;
536 			memcpy(outbuf, params->host_mac, length);
537 			retval = 0;
538 		}
539 		break;
540 
541 	/* mandatory */
542 	case OID_802_3_MULTICAST_LIST:
543 		debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
544 		/* Multicast base address only */
545 		*outbuf = __constant_cpu_to_le32(0xE0000000);
546 		retval = 0;
547 		break;
548 
549 	/* mandatory */
550 	case OID_802_3_MAXIMUM_LIST_SIZE:
551 		debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
552 		/* Multicast base address only */
553 		*outbuf = __constant_cpu_to_le32(1);
554 		retval = 0;
555 		break;
556 
557 	case OID_802_3_MAC_OPTIONS:
558 		debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
559 		break;
560 
561 	/* ieee802.3 statistics OIDs (table 4-4) */
562 
563 	/* mandatory */
564 	case OID_802_3_RCV_ERROR_ALIGNMENT:
565 		debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
566 		if (params->stats) {
567 			*outbuf = cpu_to_le32(params->stats->rx_frame_errors);
568 			retval = 0;
569 		}
570 		break;
571 
572 	/* mandatory */
573 	case OID_802_3_XMIT_ONE_COLLISION:
574 		debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
575 		*outbuf = __constant_cpu_to_le32(0);
576 		retval = 0;
577 		break;
578 
579 	/* mandatory */
580 	case OID_802_3_XMIT_MORE_COLLISIONS:
581 		debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
582 		*outbuf = __constant_cpu_to_le32(0);
583 		retval = 0;
584 		break;
585 
586 #ifdef	RNDIS_OPTIONAL_STATS
587 	case OID_802_3_XMIT_DEFERRED:
588 		debug("%s: OID_802_3_XMIT_DEFERRED\n", __func__);
589 		/* TODO */
590 		break;
591 
592 	case OID_802_3_XMIT_MAX_COLLISIONS:
593 		debug("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __func__);
594 		/* TODO */
595 		break;
596 
597 	case OID_802_3_RCV_OVERRUN:
598 		debug("%s: OID_802_3_RCV_OVERRUN\n", __func__);
599 		/* TODO */
600 		break;
601 
602 	case OID_802_3_XMIT_UNDERRUN:
603 		debug("%s: OID_802_3_XMIT_UNDERRUN\n", __func__);
604 		/* TODO */
605 		break;
606 
607 	case OID_802_3_XMIT_HEARTBEAT_FAILURE:
608 		debug("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __func__);
609 		/* TODO */
610 		break;
611 
612 	case OID_802_3_XMIT_TIMES_CRS_LOST:
613 		debug("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __func__);
614 		/* TODO */
615 		break;
616 
617 	case OID_802_3_XMIT_LATE_COLLISIONS:
618 		debug("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __func__);
619 		/* TODO */
620 		break;
621 #endif	/* RNDIS_OPTIONAL_STATS */
622 
623 #ifdef	RNDIS_PM
624 	/* power management OIDs (table 4-5) */
625 	case OID_PNP_CAPABILITIES:
626 		debug("%s: OID_PNP_CAPABILITIES\n", __func__);
627 
628 		/* for now, no wakeup capabilities */
629 		length = sizeof(struct NDIS_PNP_CAPABILITIES);
630 		memset(outbuf, 0, length);
631 		retval = 0;
632 		break;
633 	case OID_PNP_QUERY_POWER:
634 		debug("%s: OID_PNP_QUERY_POWER D%d\n", __func__,
635 				get_unaligned_le32(buf) - 1);
636 		/*
637 		 * only suspend is a real power state, and
638 		 * it can't be entered by OID_PNP_SET_POWER...
639 		 */
640 		length = 0;
641 		retval = 0;
642 		break;
643 #endif
644 
645 	default:
646 		debug("%s: query unknown OID 0x%08X\n", __func__, OID);
647 	}
648 	if (retval < 0)
649 		length = 0;
650 
651 	resp->InformationBufferLength = cpu_to_le32(length);
652 	r->length = length + sizeof *resp;
653 	resp->MessageLength = cpu_to_le32(r->length);
654 	return retval;
655 }
656 
657 static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len,
658 				rndis_resp_t *r)
659 {
660 	rndis_set_cmplt_type		*resp;
661 	int				retval = -ENOTSUPP;
662 	struct rndis_params		*params;
663 #if (defined(DEBUG) && defined(DEBUG_VERBOSE)) || defined(RNDIS_PM)
664 	int				i;
665 #endif
666 
667 	if (!r)
668 		return -ENOMEM;
669 	resp = (rndis_set_cmplt_type *) r->buf;
670 	if (!resp)
671 		return -ENOMEM;
672 
673 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
674 	if (buf_len) {
675 		debug("set OID %08x value, len %d:\n", OID, buf_len);
676 		for (i = 0; i < buf_len; i += 16) {
677 			debug("%03d: %08x %08x %08x %08x\n", i,
678 				get_unaligned_le32(&buf[i]),
679 				get_unaligned_le32(&buf[i + 4]),
680 				get_unaligned_le32(&buf[i + 8]),
681 				get_unaligned_le32(&buf[i + 12]));
682 		}
683 	}
684 #endif
685 
686 	params = &rndis_per_dev_params[configNr];
687 	switch (OID) {
688 	case OID_GEN_CURRENT_PACKET_FILTER:
689 
690 		/*
691 		 * these NDIS_PACKET_TYPE_* bitflags are shared with
692 		 * cdc_filter; it's not RNDIS-specific
693 		 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
694 		 *	PROMISCUOUS, DIRECTED,
695 		 *	MULTICAST, ALL_MULTICAST, BROADCAST
696 		 */
697 		*params->filter = (u16) get_unaligned_le32(buf);
698 		debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
699 			__func__, *params->filter);
700 
701 		/*
702 		 * this call has a significant side effect:  it's
703 		 * what makes the packet flow start and stop, like
704 		 * activating the CDC Ethernet altsetting.
705 		 */
706 #ifdef	RNDIS_PM
707 update_linkstate:
708 #endif
709 		retval = 0;
710 		if (*params->filter)
711 			params->state = RNDIS_DATA_INITIALIZED;
712 		else
713 			params->state = RNDIS_INITIALIZED;
714 		break;
715 
716 	case OID_802_3_MULTICAST_LIST:
717 		/* I think we can ignore this */
718 		debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
719 		retval = 0;
720 		break;
721 #if 0
722 	case OID_GEN_RNDIS_CONFIG_PARAMETER:
723 		{
724 		struct rndis_config_parameter	*param;
725 		param = (struct rndis_config_parameter *) buf;
726 		debug("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
727 			__func__,
728 			min(cpu_to_le32(param->ParameterNameLength), 80),
729 			buf + param->ParameterNameOffset);
730 		retval = 0;
731 		}
732 		break;
733 #endif
734 
735 #ifdef	RNDIS_PM
736 	case OID_PNP_SET_POWER:
737 		/*
738 		 * The only real power state is USB suspend, and RNDIS requests
739 		 * can't enter it; this one isn't really about power.  After
740 		 * resuming, Windows forces a reset, and then SET_POWER D0.
741 		 * FIXME ... then things go batty; Windows wedges itself.
742 		 */
743 		i = get_unaligned_le32(buf);
744 		debug("%s: OID_PNP_SET_POWER D%d\n", __func__, i - 1);
745 		switch (i) {
746 		case NdisDeviceStateD0:
747 			*params->filter = params->saved_filter;
748 			goto update_linkstate;
749 		case NdisDeviceStateD3:
750 		case NdisDeviceStateD2:
751 		case NdisDeviceStateD1:
752 			params->saved_filter = *params->filter;
753 			retval = 0;
754 			break;
755 		}
756 		break;
757 
758 #ifdef	RNDIS_WAKEUP
759 	/*
760 	 * no wakeup support advertised, so wakeup OIDs always fail:
761 	 *  - OID_PNP_ENABLE_WAKE_UP
762 	 *  - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN
763 	 */
764 #endif
765 
766 #endif	/* RNDIS_PM */
767 
768 	default:
769 		debug("%s: set unknown OID 0x%08X, size %d\n",
770 			__func__, OID, buf_len);
771 	}
772 
773 	return retval;
774 }
775 
776 /*
777  * Response Functions
778  */
779 
780 static int rndis_init_response(int configNr, rndis_init_msg_type *buf)
781 {
782 	rndis_init_cmplt_type	*resp;
783 	rndis_resp_t            *r;
784 
785 	if (!rndis_per_dev_params[configNr].dev)
786 		return -ENOTSUPP;
787 
788 	r = rndis_add_response(configNr, sizeof(rndis_init_cmplt_type));
789 	if (!r)
790 		return -ENOMEM;
791 	resp = (rndis_init_cmplt_type *) r->buf;
792 
793 	resp->MessageType = __constant_cpu_to_le32(
794 			REMOTE_NDIS_INITIALIZE_CMPLT);
795 	resp->MessageLength = __constant_cpu_to_le32(52);
796 	resp->RequestID = get_unaligned(&buf->RequestID); /* Still LE in msg buffer */
797 	resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
798 	resp->MajorVersion = __constant_cpu_to_le32(RNDIS_MAJOR_VERSION);
799 	resp->MinorVersion = __constant_cpu_to_le32(RNDIS_MINOR_VERSION);
800 	resp->DeviceFlags = __constant_cpu_to_le32(RNDIS_DF_CONNECTIONLESS);
801 	resp->Medium = __constant_cpu_to_le32(RNDIS_MEDIUM_802_3);
802 	resp->MaxPacketsPerTransfer = __constant_cpu_to_le32(1);
803 	resp->MaxTransferSize = cpu_to_le32(
804 		  rndis_per_dev_params[configNr].mtu
805 		+ ETHER_HDR_SIZE
806 		+ sizeof(struct rndis_packet_msg_type)
807 		+ 22);
808 	resp->PacketAlignmentFactor = __constant_cpu_to_le32(0);
809 	resp->AFListOffset = __constant_cpu_to_le32(0);
810 	resp->AFListSize = __constant_cpu_to_le32(0);
811 
812 	if (rndis_per_dev_params[configNr].ack)
813 		rndis_per_dev_params[configNr].ack(
814 			rndis_per_dev_params[configNr].dev);
815 
816 	return 0;
817 }
818 
819 static int rndis_query_response(int configNr, rndis_query_msg_type *buf)
820 {
821 	rndis_query_cmplt_type *resp;
822 	rndis_resp_t            *r;
823 
824 	debug("%s: OID = %08X\n", __func__, get_unaligned_le32(&buf->OID));
825 	if (!rndis_per_dev_params[configNr].dev)
826 		return -ENOTSUPP;
827 
828 	/*
829 	 * we need more memory:
830 	 * gen_ndis_query_resp expects enough space for
831 	 * rndis_query_cmplt_type followed by data.
832 	 * oid_supported_list is the largest data reply
833 	 */
834 	r = rndis_add_response(configNr,
835 		sizeof(oid_supported_list) + sizeof(rndis_query_cmplt_type));
836 	if (!r)
837 		return -ENOMEM;
838 	resp = (rndis_query_cmplt_type *) r->buf;
839 
840 	resp->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_QUERY_CMPLT);
841 	resp->RequestID = get_unaligned(&buf->RequestID); /* Still LE in msg buffer */
842 
843 	if (gen_ndis_query_resp(configNr, get_unaligned_le32(&buf->OID),
844 			get_unaligned_le32(&buf->InformationBufferOffset)
845 					+ 8 + (u8 *) buf,
846 			get_unaligned_le32(&buf->InformationBufferLength),
847 			r)) {
848 		/* OID not supported */
849 		resp->Status = __constant_cpu_to_le32(
850 						RNDIS_STATUS_NOT_SUPPORTED);
851 		resp->MessageLength = __constant_cpu_to_le32(sizeof *resp);
852 		resp->InformationBufferLength = __constant_cpu_to_le32(0);
853 		resp->InformationBufferOffset = __constant_cpu_to_le32(0);
854 	} else
855 		resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
856 
857 	if (rndis_per_dev_params[configNr].ack)
858 		rndis_per_dev_params[configNr].ack(
859 			rndis_per_dev_params[configNr].dev);
860 	return 0;
861 }
862 
863 static int rndis_set_response(int configNr, rndis_set_msg_type *buf)
864 {
865 	u32			BufLength, BufOffset;
866 	rndis_set_cmplt_type	*resp;
867 	rndis_resp_t		*r;
868 
869 	r = rndis_add_response(configNr, sizeof(rndis_set_cmplt_type));
870 	if (!r)
871 		return -ENOMEM;
872 	resp = (rndis_set_cmplt_type *) r->buf;
873 
874 	BufLength = get_unaligned_le32(&buf->InformationBufferLength);
875 	BufOffset = get_unaligned_le32(&buf->InformationBufferOffset);
876 
877 #ifdef	VERBOSE
878 	debug("%s: Length: %d\n", __func__, BufLength);
879 	debug("%s: Offset: %d\n", __func__, BufOffset);
880 	debug("%s: InfoBuffer: ", __func__);
881 
882 	for (i = 0; i < BufLength; i++)
883 		debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
884 
885 	debug("\n");
886 #endif
887 
888 	resp->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_SET_CMPLT);
889 	resp->MessageLength = __constant_cpu_to_le32(16);
890 	resp->RequestID = get_unaligned(&buf->RequestID); /* Still LE in msg buffer */
891 	if (gen_ndis_set_resp(configNr, get_unaligned_le32(&buf->OID),
892 			((u8 *) buf) + 8 + BufOffset, BufLength, r))
893 		resp->Status = __constant_cpu_to_le32(
894 						RNDIS_STATUS_NOT_SUPPORTED);
895 	else
896 		resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
897 
898 	if (rndis_per_dev_params[configNr].ack)
899 		rndis_per_dev_params[configNr].ack(
900 			rndis_per_dev_params[configNr].dev);
901 
902 	return 0;
903 }
904 
905 static int rndis_reset_response(int configNr, rndis_reset_msg_type *buf)
906 {
907 	rndis_reset_cmplt_type	*resp;
908 	rndis_resp_t		*r;
909 
910 	r = rndis_add_response(configNr, sizeof(rndis_reset_cmplt_type));
911 	if (!r)
912 		return -ENOMEM;
913 	resp = (rndis_reset_cmplt_type *) r->buf;
914 
915 	resp->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_RESET_CMPLT);
916 	resp->MessageLength = __constant_cpu_to_le32(16);
917 	resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
918 	/* resent information */
919 	resp->AddressingReset = __constant_cpu_to_le32(1);
920 
921 	if (rndis_per_dev_params[configNr].ack)
922 		rndis_per_dev_params[configNr].ack(
923 			rndis_per_dev_params[configNr].dev);
924 
925 	return 0;
926 }
927 
928 static int rndis_keepalive_response(int configNr,
929 					rndis_keepalive_msg_type *buf)
930 {
931 	rndis_keepalive_cmplt_type	*resp;
932 	rndis_resp_t			*r;
933 
934 	/* host "should" check only in RNDIS_DATA_INITIALIZED state */
935 
936 	r = rndis_add_response(configNr, sizeof(rndis_keepalive_cmplt_type));
937 	if (!r)
938 		return -ENOMEM;
939 	resp = (rndis_keepalive_cmplt_type *) r->buf;
940 
941 	resp->MessageType = __constant_cpu_to_le32(
942 			REMOTE_NDIS_KEEPALIVE_CMPLT);
943 	resp->MessageLength = __constant_cpu_to_le32(16);
944 	resp->RequestID = get_unaligned(&buf->RequestID); /* Still LE in msg buffer */
945 	resp->Status = __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS);
946 
947 	if (rndis_per_dev_params[configNr].ack)
948 		rndis_per_dev_params[configNr].ack(
949 			rndis_per_dev_params[configNr].dev);
950 
951 	return 0;
952 }
953 
954 
955 /*
956  * Device to Host Comunication
957  */
958 static int rndis_indicate_status_msg(int configNr, u32 status)
959 {
960 	rndis_indicate_status_msg_type	*resp;
961 	rndis_resp_t			*r;
962 
963 	if (rndis_per_dev_params[configNr].state == RNDIS_UNINITIALIZED)
964 		return -ENOTSUPP;
965 
966 	r = rndis_add_response(configNr,
967 				sizeof(rndis_indicate_status_msg_type));
968 	if (!r)
969 		return -ENOMEM;
970 	resp = (rndis_indicate_status_msg_type *) r->buf;
971 
972 	resp->MessageType = __constant_cpu_to_le32(
973 			REMOTE_NDIS_INDICATE_STATUS_MSG);
974 	resp->MessageLength = __constant_cpu_to_le32(20);
975 	resp->Status = cpu_to_le32(status);
976 	resp->StatusBufferLength = __constant_cpu_to_le32(0);
977 	resp->StatusBufferOffset = __constant_cpu_to_le32(0);
978 
979 	if (rndis_per_dev_params[configNr].ack)
980 		rndis_per_dev_params[configNr].ack(
981 			rndis_per_dev_params[configNr].dev);
982 	return 0;
983 }
984 
985 int rndis_signal_connect(int configNr)
986 {
987 	rndis_per_dev_params[configNr].media_state
988 			= NDIS_MEDIA_STATE_CONNECTED;
989 	return rndis_indicate_status_msg(configNr,
990 					  RNDIS_STATUS_MEDIA_CONNECT);
991 }
992 
993 int rndis_signal_disconnect(int configNr)
994 {
995 	rndis_per_dev_params[configNr].media_state
996 			= NDIS_MEDIA_STATE_DISCONNECTED;
997 
998 #ifdef RNDIS_COMPLETE_SIGNAL_DISCONNECT
999 	return rndis_indicate_status_msg(configNr,
1000 					  RNDIS_STATUS_MEDIA_DISCONNECT);
1001 #else
1002 	return 0;
1003 #endif
1004 }
1005 
1006 void rndis_uninit(int configNr)
1007 {
1008 	u8 *buf;
1009 	u32 length;
1010 
1011 	if (configNr >= RNDIS_MAX_CONFIGS)
1012 		return;
1013 	rndis_per_dev_params[configNr].used = 0;
1014 	rndis_per_dev_params[configNr].state = RNDIS_UNINITIALIZED;
1015 
1016 	/* drain the response queue */
1017 	while ((buf = rndis_get_next_response(configNr, &length)))
1018 		rndis_free_response(configNr, buf);
1019 }
1020 
1021 void rndis_set_host_mac(int configNr, const u8 *addr)
1022 {
1023 	rndis_per_dev_params[configNr].host_mac = addr;
1024 }
1025 
1026 enum rndis_state rndis_get_state(int configNr)
1027 {
1028 	if (configNr >= RNDIS_MAX_CONFIGS || configNr < 0)
1029 		return -ENOTSUPP;
1030 	return rndis_per_dev_params[configNr].state;
1031 }
1032 
1033 /*
1034  * Message Parser
1035  */
1036 int rndis_msg_parser(u8 configNr, u8 *buf)
1037 {
1038 	u32				MsgType, MsgLength;
1039 	__le32				*tmp;
1040 	struct rndis_params		*params;
1041 
1042 	debug("%s: configNr = %d, %p\n", __func__, configNr, buf);
1043 
1044 	if (!buf)
1045 		return -ENOMEM;
1046 
1047 	tmp = (__le32 *) buf;
1048 	MsgType   = get_unaligned_le32(tmp++);
1049 	MsgLength = get_unaligned_le32(tmp++);
1050 
1051 	if (configNr >= RNDIS_MAX_CONFIGS)
1052 		return -ENOTSUPP;
1053 	params = &rndis_per_dev_params[configNr];
1054 
1055 	/*
1056 	 * NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
1057 	 * rx/tx statistics and link status, in addition to KEEPALIVE traffic
1058 	 * and normal HC level polling to see if there's any IN traffic.
1059 	 */
1060 
1061 	/* For USB: responses may take up to 10 seconds */
1062 	switch (MsgType) {
1063 	case REMOTE_NDIS_INITIALIZE_MSG:
1064 		debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n", __func__);
1065 		params->state = RNDIS_INITIALIZED;
1066 		return  rndis_init_response(configNr,
1067 					(rndis_init_msg_type *) buf);
1068 
1069 	case REMOTE_NDIS_HALT_MSG:
1070 		debug("%s: REMOTE_NDIS_HALT_MSG\n", __func__);
1071 		params->state = RNDIS_UNINITIALIZED;
1072 		return 0;
1073 
1074 	case REMOTE_NDIS_QUERY_MSG:
1075 		return rndis_query_response(configNr,
1076 					(rndis_query_msg_type *) buf);
1077 
1078 	case REMOTE_NDIS_SET_MSG:
1079 		return rndis_set_response(configNr,
1080 					(rndis_set_msg_type *) buf);
1081 
1082 	case REMOTE_NDIS_RESET_MSG:
1083 		debug("%s: REMOTE_NDIS_RESET_MSG\n", __func__);
1084 		return rndis_reset_response(configNr,
1085 					(rndis_reset_msg_type *) buf);
1086 
1087 	case REMOTE_NDIS_KEEPALIVE_MSG:
1088 		/* For USB: host does this every 5 seconds */
1089 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
1090 		debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", __func__);
1091 #endif
1092 		return rndis_keepalive_response(configNr,
1093 					(rndis_keepalive_msg_type *) buf);
1094 
1095 	default:
1096 		/*
1097 		 * At least Windows XP emits some undefined RNDIS messages.
1098 		 * In one case those messages seemed to relate to the host
1099 		 * suspending itself.
1100 		 */
1101 		debug("%s: unknown RNDIS message 0x%08X len %d\n",
1102 			__func__ , MsgType, MsgLength);
1103 		{
1104 			unsigned i;
1105 			for (i = 0; i < MsgLength; i += 16) {
1106 				debug("%03d: "
1107 					" %02x %02x %02x %02x"
1108 					" %02x %02x %02x %02x"
1109 					" %02x %02x %02x %02x"
1110 					" %02x %02x %02x %02x"
1111 					"\n",
1112 					i,
1113 					buf[i], buf[i+1],
1114 						buf[i+2], buf[i+3],
1115 					buf[i+4], buf[i+5],
1116 						buf[i+6], buf[i+7],
1117 					buf[i+8], buf[i+9],
1118 						buf[i+10], buf[i+11],
1119 					buf[i+12], buf[i+13],
1120 						buf[i+14], buf[i+15]);
1121 			}
1122 		}
1123 		break;
1124 	}
1125 
1126 	return -ENOTSUPP;
1127 }
1128 
1129 int rndis_register(int (*rndis_control_ack)(struct eth_device *))
1130 {
1131 	u8 i;
1132 
1133 	for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1134 		if (!rndis_per_dev_params[i].used) {
1135 			rndis_per_dev_params[i].used = 1;
1136 			rndis_per_dev_params[i].ack = rndis_control_ack;
1137 			debug("%s: configNr = %d\n", __func__, i);
1138 			return i;
1139 		}
1140 	}
1141 	debug("%s failed\n", __func__);
1142 
1143 	return -1;
1144 }
1145 
1146 void rndis_deregister(int configNr)
1147 {
1148 	debug("%s: configNr = %d\n", __func__, configNr);
1149 
1150 	if (configNr >= RNDIS_MAX_CONFIGS)
1151 		return;
1152 	rndis_per_dev_params[configNr].used = 0;
1153 
1154 	return;
1155 }
1156 
1157 int rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu,
1158 			struct net_device_stats *stats,	u16 *cdc_filter)
1159 {
1160 	debug("%s: configNr = %d\n", __func__, configNr);
1161 	if (!dev || !stats)
1162 		return -1;
1163 	if (configNr >= RNDIS_MAX_CONFIGS)
1164 		return -1;
1165 
1166 	rndis_per_dev_params[configNr].dev = dev;
1167 	rndis_per_dev_params[configNr].stats = stats;
1168 	rndis_per_dev_params[configNr].mtu = mtu;
1169 	rndis_per_dev_params[configNr].filter = cdc_filter;
1170 
1171 	return 0;
1172 }
1173 
1174 int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr)
1175 {
1176 	debug("%s: configNr = %d\n", __func__, configNr);
1177 	if (!vendorDescr)
1178 		return -1;
1179 	if (configNr >= RNDIS_MAX_CONFIGS)
1180 		return -1;
1181 
1182 	rndis_per_dev_params[configNr].vendorID = vendorID;
1183 	rndis_per_dev_params[configNr].vendorDescr = vendorDescr;
1184 
1185 	return 0;
1186 }
1187 
1188 int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed)
1189 {
1190 	debug("%s: configNr = %d, %u %u\n", __func__, configNr, medium, speed);
1191 	if (configNr >= RNDIS_MAX_CONFIGS)
1192 		return -1;
1193 
1194 	rndis_per_dev_params[configNr].medium = medium;
1195 	rndis_per_dev_params[configNr].speed = speed;
1196 
1197 	return 0;
1198 }
1199 
1200 void rndis_add_hdr(void *buf, int length)
1201 {
1202 	struct rndis_packet_msg_type	*header;
1203 
1204 	header = buf;
1205 	memset(header, 0, sizeof *header);
1206 	header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
1207 	header->MessageLength = cpu_to_le32(length + sizeof *header);
1208 	header->DataOffset = __constant_cpu_to_le32(36);
1209 	header->DataLength = cpu_to_le32(length);
1210 }
1211 
1212 void rndis_free_response(int configNr, u8 *buf)
1213 {
1214 	rndis_resp_t		*r;
1215 	struct list_head	*act, *tmp;
1216 
1217 	list_for_each_safe(act, tmp,
1218 			&(rndis_per_dev_params[configNr].resp_queue))
1219 	{
1220 		r = list_entry(act, rndis_resp_t, list);
1221 		if (r && r->buf == buf) {
1222 			list_del(&r->list);
1223 			free(r);
1224 		}
1225 	}
1226 }
1227 
1228 u8 *rndis_get_next_response(int configNr, u32 *length)
1229 {
1230 	rndis_resp_t		*r;
1231 	struct list_head	*act, *tmp;
1232 
1233 	if (!length)
1234 		return NULL;
1235 
1236 	list_for_each_safe(act, tmp,
1237 			&(rndis_per_dev_params[configNr].resp_queue))
1238 	{
1239 		r = list_entry(act, rndis_resp_t, list);
1240 		if (!r->send) {
1241 			r->send = 1;
1242 			*length = r->length;
1243 			return r->buf;
1244 		}
1245 	}
1246 
1247 	return NULL;
1248 }
1249 
1250 static rndis_resp_t *rndis_add_response(int configNr, u32 length)
1251 {
1252 	rndis_resp_t	*r;
1253 
1254 	/* NOTE:  this gets copied into ether.c USB_BUFSIZ bytes ... */
1255 	r = malloc(sizeof(rndis_resp_t) + length);
1256 	if (!r)
1257 		return NULL;
1258 
1259 	r->buf = (u8 *) (r + 1);
1260 	r->length = length;
1261 	r->send = 0;
1262 
1263 	list_add_tail(&r->list,
1264 		&(rndis_per_dev_params[configNr].resp_queue));
1265 	return r;
1266 }
1267 
1268 int rndis_rm_hdr(void *buf, int length)
1269 {
1270 	/* tmp points to a struct rndis_packet_msg_type */
1271 	__le32		*tmp = buf;
1272 	int		offs, len;
1273 
1274 	/* MessageType, MessageLength */
1275 	if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
1276 			!= get_unaligned(tmp++))
1277 		return -EINVAL;
1278 	tmp++;
1279 
1280 	/* DataOffset, DataLength */
1281 	offs = get_unaligned_le32(tmp++) + 8 /* offset of DataOffset */;
1282 	if (offs != sizeof(struct rndis_packet_msg_type))
1283 		debug("%s: unexpected DataOffset: %d\n", __func__, offs);
1284 	if (offs >= length)
1285 		return -EOVERFLOW;
1286 
1287 	len = get_unaligned_le32(tmp++);
1288 	if (len + sizeof(struct rndis_packet_msg_type) != length)
1289 		debug("%s: unexpected DataLength: %d, packet length=%d\n",
1290 				__func__, len, length);
1291 
1292 	memmove(buf, buf + offs, len);
1293 
1294 	return offs;
1295 }
1296 
1297 int rndis_init(void)
1298 {
1299 	u8 i;
1300 
1301 	for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1302 		rndis_per_dev_params[i].confignr = i;
1303 		rndis_per_dev_params[i].used = 0;
1304 		rndis_per_dev_params[i].state = RNDIS_UNINITIALIZED;
1305 		rndis_per_dev_params[i].media_state
1306 				= NDIS_MEDIA_STATE_DISCONNECTED;
1307 		INIT_LIST_HEAD(&(rndis_per_dev_params[i].resp_queue));
1308 	}
1309 
1310 	return 0;
1311 }
1312 
1313 void rndis_exit(void)
1314 {
1315 	/* Nothing to do */
1316 }
1317