]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/usb/gadget/rndis.c
886c0936e6ae74e2b7c2e6d8366039412bf855f9
[karo-tx-uboot.git] / drivers / usb / gadget / rndis.c
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
60 static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS];
61
62 /* Driver Version */
63 static const __le32 rndis_driver_version = __constant_cpu_to_le32(1);
64
65 /* Function Prototypes */
66 static rndis_resp_t *rndis_add_response(int configNr, u32 length);
67
68
69 /* supported OIDs */
70 static 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 */
155 static 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
657 static 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
707 update_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
780 static 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
819 static 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
863 static 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
905 static 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
928 static 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  */
958 static 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
985 int 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
993 int 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
1006 void 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
1021 void rndis_set_host_mac(int configNr, const u8 *addr)
1022 {
1023         rndis_per_dev_params[configNr].host_mac = addr;
1024 }
1025
1026 enum 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  */
1036 int 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
1129 int 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
1146 void 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
1157 int 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
1174 int 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
1188 int 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
1200 void 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
1212 void 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
1228 u8 *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
1250 static 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
1268 int 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
1297 int 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
1313 void rndis_exit(void)
1314 {
1315         /* Nothing to do */
1316 }
1317