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