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