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