]> git.sur5r.net Git - u-boot/blob - drivers/usb/gadget/rndis.c
Merge branch 'master' of git://www.denx.de/git/u-boot-imx
[u-boot] / drivers / usb / gadget / rndis.c
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 }