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