Home | History | Annotate | Download | only in gadget
      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 (at) auerswald.de>
     12  *		Fixed message length bug in init_response
     13  *
     14  * 03/25/2004 Kai-Uwe Bloem <linux-development (at) 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