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