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