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