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