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