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