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