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