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