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