4 * Version: $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $
6 * Authors: Benedikt Spranger, Pengutronix
7 * Robert Schwebel, Pengutronix
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.
13 * This software was originally developed in conformance with
14 * Microsoft's Remote NDIS Specification License Agreement.
16 * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
17 * Fixed message length bug in init_response
19 * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
20 * Fixed rndis_rm_hdr length bug.
22 * Copyright (C) 2004 by David Brownell
23 * updates to merge with Linux 2.6, better match RNDIS spec
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>
38 #include <asm/byteorder.h>
39 #include <asm/system.h>
40 #include <asm/unaligned.h>
49 /* The driver for your USB chip needs to support ep0 OUT to work with
50 * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
52 * Windows hosts need an INF file like Documentation/usb/linux.inf
53 * and will be happier if you provide the host_addr module parameter.
57 #define DEBUG(str,args...) do { \
59 printk(KERN_DEBUG str , ## args ); \
61 static int rndis_debug
= 0;
63 module_param (rndis_debug
, bool, 0);
64 MODULE_PARM_DESC (rndis_debug
, "enable debugging");
69 #define DEBUG(str,args...) do{}while(0)
72 #define RNDIS_MAX_CONFIGS 1
75 static rndis_params rndis_per_dev_params
[RNDIS_MAX_CONFIGS
];
78 static const __le32 rndis_driver_version
= __constant_cpu_to_le32 (1);
80 /* Function Prototypes */
81 static int rndis_init_response (int configNr
, rndis_init_msg_type
*buf
);
82 static int rndis_query_response (int configNr
, rndis_query_msg_type
*buf
);
83 static int rndis_set_response (int configNr
, rndis_set_msg_type
*buf
);
84 static int rndis_reset_response (int configNr
, rndis_reset_msg_type
*buf
);
85 static int rndis_keepalive_response (int configNr
,
86 rndis_keepalive_msg_type
*buf
);
88 static rndis_resp_t
*rndis_add_response (int configNr
, u32 length
);
92 static int gen_ndis_query_resp (int configNr
, u32 OID
, rndis_resp_t
*r
)
94 int retval
= -ENOTSUPP
;
98 rndis_query_cmplt_type
*resp
;
100 if (!r
) return -ENOMEM
;
101 resp
= (rndis_query_cmplt_type
*) r
->buf
;
103 if (!resp
) return -ENOMEM
;
107 /* general oids (table 4-1) */
110 case OID_GEN_SUPPORTED_LIST
:
111 DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__
);
112 length
= sizeof (oid_supported_list
);
113 count
= length
/ sizeof (u32
);
114 tmp
= (__le32
*) ((u8
*)resp
+ 24);
115 for (i
= 0; i
< count
; i
++)
116 tmp
[i
] = cpu_to_le32 (oid_supported_list
[i
]);
121 case OID_GEN_HARDWARE_STATUS
:
122 DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__
);
125 * Hardware must be ready to receive high level protocols.
127 * reddite ergo quae sunt Caesaris Caesari
128 * et quae sunt Dei Deo!
130 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
135 case OID_GEN_MEDIA_SUPPORTED
:
136 DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__
);
138 *((__le32
*) resp
+ 6) = cpu_to_le32 (
139 rndis_per_dev_params
[configNr
].medium
);
144 case OID_GEN_MEDIA_IN_USE
:
145 DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__
);
147 /* one medium, one transport... (maybe you do it better) */
148 *((__le32
*) resp
+ 6) = cpu_to_le32 (
149 rndis_per_dev_params
[configNr
].medium
);
154 case OID_GEN_MAXIMUM_FRAME_SIZE
:
155 DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__
);
156 if (rndis_per_dev_params
[configNr
].dev
) {
158 *((__le32
*) resp
+ 6) = cpu_to_le32 (
159 rndis_per_dev_params
[configNr
].dev
->mtu
);
162 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
168 case OID_GEN_LINK_SPEED
:
169 // DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
171 if (rndis_per_dev_params
[configNr
].media_state
172 == NDIS_MEDIA_STATE_DISCONNECTED
)
173 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
175 *((__le32
*) resp
+ 6) = cpu_to_le32 (
176 rndis_per_dev_params
[configNr
].speed
);
181 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
182 DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__
);
183 if (rndis_per_dev_params
[configNr
].dev
) {
185 *((__le32
*) resp
+ 6) = cpu_to_le32 (
186 rndis_per_dev_params
[configNr
].dev
->mtu
);
192 case OID_GEN_RECEIVE_BLOCK_SIZE
:
193 DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__
);
194 if (rndis_per_dev_params
[configNr
].dev
) {
196 *((__le32
*) resp
+ 6) = cpu_to_le32 (
197 rndis_per_dev_params
[configNr
].dev
->mtu
);
203 case OID_GEN_VENDOR_ID
:
204 DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__
);
206 *((__le32
*) resp
+ 6) = cpu_to_le32 (
207 rndis_per_dev_params
[configNr
].vendorID
);
212 case OID_GEN_VENDOR_DESCRIPTION
:
213 DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__
);
214 length
= strlen (rndis_per_dev_params
[configNr
].vendorDescr
);
215 memcpy ((u8
*) resp
+ 24,
216 rndis_per_dev_params
[configNr
].vendorDescr
, length
);
220 case OID_GEN_VENDOR_DRIVER_VERSION
:
221 DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__
);
224 *((__le32
*) resp
+ 6) = rndis_driver_version
;
229 case OID_GEN_CURRENT_PACKET_FILTER
:
230 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__
);
232 *((__le32
*) resp
+ 6) = cpu_to_le32 (
233 rndis_per_dev_params
[configNr
].filter
);
238 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
239 DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__
);
241 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32(
242 RNDIS_MAX_TOTAL_SIZE
);
247 case OID_GEN_MEDIA_CONNECT_STATUS
:
248 DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__
);
250 *((__le32
*) resp
+ 6) = cpu_to_le32 (
251 rndis_per_dev_params
[configNr
]
256 case OID_GEN_PHYSICAL_MEDIUM
:
257 DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__
);
259 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
263 /* The RNDIS specification is incomplete/wrong. Some versions
264 * of MS-Windows expect OIDs that aren't specified there. Other
265 * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
267 case OID_GEN_MAC_OPTIONS
: /* from WinME */
268 DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__
);
270 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32(
271 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
272 | NDIS_MAC_OPTION_FULL_DUPLEX
);
276 /* statistics OIDs (table 4-2) */
279 case OID_GEN_XMIT_OK
:
280 DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__
);
281 if (rndis_per_dev_params
[configNr
].stats
) {
283 *((__le32
*) resp
+ 6) = cpu_to_le32 (
284 rndis_per_dev_params
[configNr
].stats
->tx_packets
-
285 rndis_per_dev_params
[configNr
].stats
->tx_errors
-
286 rndis_per_dev_params
[configNr
].stats
->tx_dropped
);
289 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
296 DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__
);
297 if (rndis_per_dev_params
[configNr
].stats
) {
299 *((__le32
*) resp
+ 6) = cpu_to_le32 (
300 rndis_per_dev_params
[configNr
].stats
->rx_packets
-
301 rndis_per_dev_params
[configNr
].stats
->rx_errors
-
302 rndis_per_dev_params
[configNr
].stats
->rx_dropped
);
305 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
311 case OID_GEN_XMIT_ERROR
:
312 DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__
);
313 if (rndis_per_dev_params
[configNr
].stats
) {
315 *((__le32
*) resp
+ 6) = cpu_to_le32 (
316 rndis_per_dev_params
[configNr
]
320 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
326 case OID_GEN_RCV_ERROR
:
327 DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__
);
328 if (rndis_per_dev_params
[configNr
].stats
) {
329 *((__le32
*) resp
+ 6) = cpu_to_le32 (
330 rndis_per_dev_params
[configNr
]
334 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
340 case OID_GEN_RCV_NO_BUFFER
:
341 DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__
);
342 if (rndis_per_dev_params
[configNr
].stats
) {
343 *((__le32
*) resp
+ 6) = cpu_to_le32 (
344 rndis_per_dev_params
[configNr
]
348 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
353 #ifdef RNDIS_OPTIONAL_STATS
354 case OID_GEN_DIRECTED_BYTES_XMIT
:
355 DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__
);
357 * Aunt Tilly's size of shoes
358 * minus antarctica count of penguins
359 * divided by weight of Alpha Centauri
361 if (rndis_per_dev_params
[configNr
].stats
) {
363 *((__le32
*) resp
+ 6) = cpu_to_le32 (
364 (rndis_per_dev_params
[configNr
]
366 rndis_per_dev_params
[configNr
]
368 rndis_per_dev_params
[configNr
]
373 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
378 case OID_GEN_DIRECTED_FRAMES_XMIT
:
379 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__
);
381 if (rndis_per_dev_params
[configNr
].stats
) {
383 *((__le32
*) resp
+ 6) = cpu_to_le32 (
384 (rndis_per_dev_params
[configNr
]
386 rndis_per_dev_params
[configNr
]
388 rndis_per_dev_params
[configNr
]
393 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
398 case OID_GEN_MULTICAST_BYTES_XMIT
:
399 DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__
);
400 if (rndis_per_dev_params
[configNr
].stats
) {
401 *((__le32
*) resp
+ 6) = cpu_to_le32 (
402 rndis_per_dev_params
[configNr
]
403 .stats
->multicast
*1234);
406 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
411 case OID_GEN_MULTICAST_FRAMES_XMIT
:
412 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__
);
413 if (rndis_per_dev_params
[configNr
].stats
) {
414 *((__le32
*) resp
+ 6) = cpu_to_le32 (
415 rndis_per_dev_params
[configNr
]
419 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
424 case OID_GEN_BROADCAST_BYTES_XMIT
:
425 DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__
);
426 if (rndis_per_dev_params
[configNr
].stats
) {
427 *((__le32
*) resp
+ 6) = cpu_to_le32 (
428 rndis_per_dev_params
[configNr
]
429 .stats
->tx_packets
/42*255);
432 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
437 case OID_GEN_BROADCAST_FRAMES_XMIT
:
438 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__
);
439 if (rndis_per_dev_params
[configNr
].stats
) {
440 *((__le32
*) resp
+ 6) = cpu_to_le32 (
441 rndis_per_dev_params
[configNr
]
442 .stats
->tx_packets
/42);
445 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
450 case OID_GEN_DIRECTED_BYTES_RCV
:
451 DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__
);
452 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
456 case OID_GEN_DIRECTED_FRAMES_RCV
:
457 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__
);
458 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
462 case OID_GEN_MULTICAST_BYTES_RCV
:
463 DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__
);
464 if (rndis_per_dev_params
[configNr
].stats
) {
465 *((__le32
*) resp
+ 6) = cpu_to_le32 (
466 rndis_per_dev_params
[configNr
]
467 .stats
->multicast
* 1111);
470 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
475 case OID_GEN_MULTICAST_FRAMES_RCV
:
476 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__
);
477 if (rndis_per_dev_params
[configNr
].stats
) {
478 *((__le32
*) resp
+ 6) = cpu_to_le32 (
479 rndis_per_dev_params
[configNr
]
483 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
488 case OID_GEN_BROADCAST_BYTES_RCV
:
489 DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__
);
490 if (rndis_per_dev_params
[configNr
].stats
) {
491 *((__le32
*) resp
+ 6) = cpu_to_le32 (
492 rndis_per_dev_params
[configNr
]
493 .stats
->rx_packets
/42*255);
496 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
501 case OID_GEN_BROADCAST_FRAMES_RCV
:
502 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__
);
503 if (rndis_per_dev_params
[configNr
].stats
) {
504 *((__le32
*) resp
+ 6) = cpu_to_le32 (
505 rndis_per_dev_params
[configNr
]
506 .stats
->rx_packets
/42);
509 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
514 case OID_GEN_RCV_CRC_ERROR
:
515 DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__
);
516 if (rndis_per_dev_params
[configNr
].stats
) {
517 *((__le32
*) resp
+ 6) = cpu_to_le32 (
518 rndis_per_dev_params
[configNr
]
519 .stats
->rx_crc_errors
);
522 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
527 case OID_GEN_TRANSMIT_QUEUE_LENGTH
:
528 DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__
);
529 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
532 #endif /* RNDIS_OPTIONAL_STATS */
534 /* ieee802.3 OIDs (table 4-3) */
537 case OID_802_3_PERMANENT_ADDRESS
:
538 DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__
);
539 if (rndis_per_dev_params
[configNr
].dev
) {
541 memcpy ((u8
*) resp
+ 24,
542 rndis_per_dev_params
[configNr
].host_mac
,
546 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
552 case OID_802_3_CURRENT_ADDRESS
:
553 DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__
);
554 if (rndis_per_dev_params
[configNr
].dev
) {
556 memcpy ((u8
*) resp
+ 24,
557 rndis_per_dev_params
[configNr
].host_mac
,
564 case OID_802_3_MULTICAST_LIST
:
565 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__
);
567 /* Multicast base address only */
568 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0xE0000000);
573 case OID_802_3_MAXIMUM_LIST_SIZE
:
574 DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__
);
576 /* Multicast base address only */
577 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (1);
581 case OID_802_3_MAC_OPTIONS
:
582 DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__
);
585 /* ieee802.3 statistics OIDs (table 4-4) */
588 case OID_802_3_RCV_ERROR_ALIGNMENT
:
589 DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__
);
590 if (rndis_per_dev_params
[configNr
].stats
)
593 *((__le32
*) resp
+ 6) = cpu_to_le32 (
594 rndis_per_dev_params
[configNr
]
595 .stats
->rx_frame_errors
);
601 case OID_802_3_XMIT_ONE_COLLISION
:
602 DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__
);
604 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
609 case OID_802_3_XMIT_MORE_COLLISIONS
:
610 DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__
);
612 *((__le32
*) resp
+ 6) = __constant_cpu_to_le32 (0);
616 #ifdef RNDIS_OPTIONAL_STATS
617 case OID_802_3_XMIT_DEFERRED
:
618 DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__
);
622 case OID_802_3_XMIT_MAX_COLLISIONS
:
623 DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__
);
627 case OID_802_3_RCV_OVERRUN
:
628 DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__
);
632 case OID_802_3_XMIT_UNDERRUN
:
633 DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__
);
637 case OID_802_3_XMIT_HEARTBEAT_FAILURE
:
638 DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__
);
642 case OID_802_3_XMIT_TIMES_CRS_LOST
:
643 DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__
);
647 case OID_802_3_XMIT_LATE_COLLISIONS
:
648 DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__
);
651 #endif /* RNDIS_OPTIONAL_STATS */
654 /* power management OIDs (table 4-5) */
655 case OID_PNP_CAPABILITIES
:
656 DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__
);
658 /* just PM, and remote wakeup on link status change
659 * (not magic packet or pattern match)
661 length
= sizeof (struct NDIS_PNP_CAPABILITIES
);
662 memset (resp
, 0, length
);
664 struct NDIS_PNP_CAPABILITIES
*caps
= (void *) resp
;
666 caps
->Flags
= NDIS_DEVICE_WAKE_UP_ENABLE
;
667 caps
->WakeUpCapabilities
.MinLinkChangeWakeUp
670 /* FIXME then use usb_gadget_wakeup(), and
671 * set USB_CONFIG_ATT_WAKEUP in config desc
676 case OID_PNP_QUERY_POWER
:
677 DEBUG("%s: OID_PNP_QUERY_POWER\n", __FUNCTION__
);
678 /* sure, handle any power state that maps to USB suspend */
684 printk (KERN_WARNING
"%s: query unknown OID 0x%08X\n",
688 resp
->InformationBufferOffset
= __constant_cpu_to_le32 (16);
689 resp
->InformationBufferLength
= cpu_to_le32 (length
);
690 resp
->MessageLength
= cpu_to_le32 (24 + length
);
691 r
->length
= 24 + length
;
695 static int gen_ndis_set_resp (u8 configNr
, u32 OID
, u8
*buf
, u32 buf_len
,
698 rndis_set_cmplt_type
*resp
;
699 int i
, retval
= -ENOTSUPP
;
700 struct rndis_params
*params
;
704 resp
= (rndis_set_cmplt_type
*) r
->buf
;
708 DEBUG("set OID %08x value, len %d:\n", OID
, buf_len
);
709 for (i
= 0; i
< buf_len
; i
+= 16) {
711 " %02x %02x %02x %02x"
712 " %02x %02x %02x %02x"
713 " %02x %02x %02x %02x"
714 " %02x %02x %02x %02x"
722 buf
[i
+10], buf
[i
+11],
723 buf
[i
+12], buf
[i
+13],
724 buf
[i
+14], buf
[i
+15]);
728 case OID_GEN_CURRENT_PACKET_FILTER
:
729 params
= &rndis_per_dev_params
[configNr
];
732 /* FIXME use these NDIS_PACKET_TYPE_* bitflags to
733 * set the cdc_filter; it's not RNDIS-specific
734 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
735 * PROMISCUOUS, DIRECTED,
736 * MULTICAST, ALL_MULTICAST, BROADCAST
738 params
->filter
= le32_to_cpup((__le32
*)buf
);
739 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
740 __FUNCTION__
, params
->filter
);
742 /* this call has a significant side effect: it's
743 * what makes the packet flow start and stop, like
744 * activating the CDC Ethernet altsetting.
746 if (params
->filter
) {
747 params
->state
= RNDIS_DATA_INITIALIZED
;
748 netif_carrier_on(params
->dev
);
749 if (netif_running(params
->dev
))
750 netif_wake_queue (params
->dev
);
752 params
->state
= RNDIS_INITIALIZED
;
753 netif_carrier_off (params
->dev
);
754 netif_stop_queue (params
->dev
);
758 case OID_802_3_MULTICAST_LIST
:
759 /* I think we can ignore this */
760 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__
);
764 case OID_GEN_RNDIS_CONFIG_PARAMETER
:
766 struct rndis_config_parameter
*param
;
767 param
= (struct rndis_config_parameter
*) buf
;
768 DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
770 min(cpu_to_le32(param
->ParameterNameLength
),80),
771 buf
+ param
->ParameterNameOffset
);
778 case OID_PNP_SET_POWER
:
779 DEBUG ("OID_PNP_SET_POWER\n");
780 /* sure, handle any power state that maps to USB suspend */
784 case OID_PNP_ENABLE_WAKE_UP
:
785 /* always-connected ... */
786 DEBUG ("OID_PNP_ENABLE_WAKE_UP\n");
790 // no PM resume patterns supported (specified where?)
791 // so OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN always fails
795 printk (KERN_WARNING
"%s: set unknown OID 0x%08X, size %d\n",
796 __FUNCTION__
, OID
, buf_len
);
806 static int rndis_init_response (int configNr
, rndis_init_msg_type
*buf
)
808 rndis_init_cmplt_type
*resp
;
811 if (!rndis_per_dev_params
[configNr
].dev
) return -ENOTSUPP
;
813 r
= rndis_add_response (configNr
, sizeof (rndis_init_cmplt_type
));
815 if (!r
) return -ENOMEM
;
817 resp
= (rndis_init_cmplt_type
*) r
->buf
;
819 if (!resp
) return -ENOMEM
;
821 resp
->MessageType
= __constant_cpu_to_le32 (
822 REMOTE_NDIS_INITIALIZE_CMPLT
);
823 resp
->MessageLength
= __constant_cpu_to_le32 (52);
824 resp
->RequestID
= buf
->RequestID
; /* Still LE in msg buffer */
825 resp
->Status
= __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS
);
826 resp
->MajorVersion
= __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION
);
827 resp
->MinorVersion
= __constant_cpu_to_le32 (RNDIS_MINOR_VERSION
);
828 resp
->DeviceFlags
= __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS
);
829 resp
->Medium
= __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3
);
830 resp
->MaxPacketsPerTransfer
= __constant_cpu_to_le32 (1);
831 resp
->MaxTransferSize
= cpu_to_le32 (
832 rndis_per_dev_params
[configNr
].dev
->mtu
833 + sizeof (struct ethhdr
)
834 + sizeof (struct rndis_packet_msg_type
)
836 resp
->PacketAlignmentFactor
= __constant_cpu_to_le32 (0);
837 resp
->AFListOffset
= __constant_cpu_to_le32 (0);
838 resp
->AFListSize
= __constant_cpu_to_le32 (0);
840 if (rndis_per_dev_params
[configNr
].ack
)
841 rndis_per_dev_params
[configNr
].ack (
842 rndis_per_dev_params
[configNr
].dev
);
847 static int rndis_query_response (int configNr
, rndis_query_msg_type
*buf
)
849 rndis_query_cmplt_type
*resp
;
852 // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
853 if (!rndis_per_dev_params
[configNr
].dev
) return -ENOTSUPP
;
856 * we need more memory:
857 * oid_supported_list is the largest answer
859 r
= rndis_add_response (configNr
, sizeof (oid_supported_list
));
861 if (!r
) return -ENOMEM
;
862 resp
= (rndis_query_cmplt_type
*) r
->buf
;
864 if (!resp
) return -ENOMEM
;
866 resp
->MessageType
= __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT
);
867 resp
->MessageLength
= __constant_cpu_to_le32 (24);
868 resp
->RequestID
= buf
->RequestID
; /* Still LE in msg buffer */
870 if (gen_ndis_query_resp (configNr
, le32_to_cpu (buf
->OID
), r
)) {
871 /* OID not supported */
872 resp
->Status
= __constant_cpu_to_le32 (
873 RNDIS_STATUS_NOT_SUPPORTED
);
874 resp
->InformationBufferLength
= __constant_cpu_to_le32 (0);
875 resp
->InformationBufferOffset
= __constant_cpu_to_le32 (0);
877 resp
->Status
= __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS
);
879 if (rndis_per_dev_params
[configNr
].ack
)
880 rndis_per_dev_params
[configNr
].ack (
881 rndis_per_dev_params
[configNr
].dev
);
885 static int rndis_set_response (int configNr
, rndis_set_msg_type
*buf
)
887 u32 BufLength
, BufOffset
;
888 rndis_set_cmplt_type
*resp
;
891 r
= rndis_add_response (configNr
, sizeof (rndis_set_cmplt_type
));
893 if (!r
) return -ENOMEM
;
894 resp
= (rndis_set_cmplt_type
*) r
->buf
;
895 if (!resp
) return -ENOMEM
;
897 BufLength
= le32_to_cpu (buf
->InformationBufferLength
);
898 BufOffset
= le32_to_cpu (buf
->InformationBufferOffset
);
901 DEBUG("%s: Length: %d\n", __FUNCTION__
, BufLength
);
902 DEBUG("%s: Offset: %d\n", __FUNCTION__
, BufOffset
);
903 DEBUG("%s: InfoBuffer: ", __FUNCTION__
);
905 for (i
= 0; i
< BufLength
; i
++) {
906 DEBUG ("%02x ", *(((u8
*) buf
) + i
+ 8 + BufOffset
));
912 resp
->MessageType
= __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT
);
913 resp
->MessageLength
= __constant_cpu_to_le32 (16);
914 resp
->RequestID
= buf
->RequestID
; /* Still LE in msg buffer */
915 if (gen_ndis_set_resp (configNr
, le32_to_cpu (buf
->OID
),
916 ((u8
*) buf
) + 8 + BufOffset
, BufLength
, r
))
917 resp
->Status
= __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED
);
918 else resp
->Status
= __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS
);
920 if (rndis_per_dev_params
[configNr
].ack
)
921 rndis_per_dev_params
[configNr
].ack (
922 rndis_per_dev_params
[configNr
].dev
);
927 static int rndis_reset_response (int configNr
, rndis_reset_msg_type
*buf
)
929 rndis_reset_cmplt_type
*resp
;
932 r
= rndis_add_response (configNr
, sizeof (rndis_reset_cmplt_type
));
934 if (!r
) return -ENOMEM
;
935 resp
= (rndis_reset_cmplt_type
*) r
->buf
;
936 if (!resp
) return -ENOMEM
;
938 resp
->MessageType
= __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT
);
939 resp
->MessageLength
= __constant_cpu_to_le32 (16);
940 resp
->Status
= __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS
);
941 /* resent information */
942 resp
->AddressingReset
= __constant_cpu_to_le32 (1);
944 if (rndis_per_dev_params
[configNr
].ack
)
945 rndis_per_dev_params
[configNr
].ack (
946 rndis_per_dev_params
[configNr
].dev
);
951 static int rndis_keepalive_response (int configNr
,
952 rndis_keepalive_msg_type
*buf
)
954 rndis_keepalive_cmplt_type
*resp
;
957 /* host "should" check only in RNDIS_DATA_INITIALIZED state */
959 r
= rndis_add_response (configNr
, sizeof (rndis_keepalive_cmplt_type
));
960 resp
= (rndis_keepalive_cmplt_type
*) r
->buf
;
961 if (!resp
) return -ENOMEM
;
963 resp
->MessageType
= __constant_cpu_to_le32 (
964 REMOTE_NDIS_KEEPALIVE_CMPLT
);
965 resp
->MessageLength
= __constant_cpu_to_le32 (16);
966 resp
->RequestID
= buf
->RequestID
; /* Still LE in msg buffer */
967 resp
->Status
= __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS
);
969 if (rndis_per_dev_params
[configNr
].ack
)
970 rndis_per_dev_params
[configNr
].ack (
971 rndis_per_dev_params
[configNr
].dev
);
978 * Device to Host Comunication
980 static int rndis_indicate_status_msg (int configNr
, u32 status
)
982 rndis_indicate_status_msg_type
*resp
;
985 if (rndis_per_dev_params
[configNr
].state
== RNDIS_UNINITIALIZED
)
988 r
= rndis_add_response (configNr
,
989 sizeof (rndis_indicate_status_msg_type
));
990 if (!r
) return -ENOMEM
;
992 resp
= (rndis_indicate_status_msg_type
*) r
->buf
;
993 if (!resp
) return -ENOMEM
;
995 resp
->MessageType
= __constant_cpu_to_le32 (
996 REMOTE_NDIS_INDICATE_STATUS_MSG
);
997 resp
->MessageLength
= __constant_cpu_to_le32 (20);
998 resp
->Status
= cpu_to_le32 (status
);
999 resp
->StatusBufferLength
= __constant_cpu_to_le32 (0);
1000 resp
->StatusBufferOffset
= __constant_cpu_to_le32 (0);
1002 if (rndis_per_dev_params
[configNr
].ack
)
1003 rndis_per_dev_params
[configNr
].ack (
1004 rndis_per_dev_params
[configNr
].dev
);
1008 int rndis_signal_connect (int configNr
)
1010 rndis_per_dev_params
[configNr
].media_state
1011 = NDIS_MEDIA_STATE_CONNECTED
;
1012 return rndis_indicate_status_msg (configNr
,
1013 RNDIS_STATUS_MEDIA_CONNECT
);
1016 int rndis_signal_disconnect (int configNr
)
1018 rndis_per_dev_params
[configNr
].media_state
1019 = NDIS_MEDIA_STATE_DISCONNECTED
;
1020 return rndis_indicate_status_msg (configNr
,
1021 RNDIS_STATUS_MEDIA_DISCONNECT
);
1024 void rndis_set_host_mac (int configNr
, const u8
*addr
)
1026 rndis_per_dev_params
[configNr
].host_mac
= addr
;
1032 int rndis_msg_parser (u8 configNr
, u8
*buf
)
1034 u32 MsgType
, MsgLength
;
1036 struct rndis_params
*params
;
1041 tmp
= (__le32
*) buf
;
1042 MsgType
= le32_to_cpup(tmp
++);
1043 MsgLength
= le32_to_cpup(tmp
++);
1045 if (configNr
>= RNDIS_MAX_CONFIGS
)
1047 params
= &rndis_per_dev_params
[configNr
];
1049 /* For USB: responses may take up to 10 seconds */
1052 case REMOTE_NDIS_INITIALIZE_MSG
:
1053 DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
1055 params
->state
= RNDIS_INITIALIZED
;
1056 return rndis_init_response (configNr
,
1057 (rndis_init_msg_type
*) buf
);
1059 case REMOTE_NDIS_HALT_MSG
:
1060 DEBUG("%s: REMOTE_NDIS_HALT_MSG\n",
1062 params
->state
= RNDIS_UNINITIALIZED
;
1064 netif_carrier_off (params
->dev
);
1065 netif_stop_queue (params
->dev
);
1069 case REMOTE_NDIS_QUERY_MSG
:
1070 return rndis_query_response (configNr
,
1071 (rndis_query_msg_type
*) buf
);
1073 case REMOTE_NDIS_SET_MSG
:
1074 return rndis_set_response (configNr
,
1075 (rndis_set_msg_type
*) buf
);
1077 case REMOTE_NDIS_RESET_MSG
:
1078 DEBUG("%s: REMOTE_NDIS_RESET_MSG\n",
1080 return rndis_reset_response (configNr
,
1081 (rndis_reset_msg_type
*) buf
);
1083 case REMOTE_NDIS_KEEPALIVE_MSG
:
1084 /* For USB: host does this every 5 seconds */
1086 DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
1089 return rndis_keepalive_response (configNr
,
1090 (rndis_keepalive_msg_type
*)
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.
1098 printk (KERN_WARNING
1099 "%s: unknown RNDIS message 0x%08X len %d\n",
1100 __FUNCTION__
, MsgType
, MsgLength
);
1103 for (i
= 0; i
< MsgLength
; i
+= 16) {
1105 " %02x %02x %02x %02x"
1106 " %02x %02x %02x %02x"
1107 " %02x %02x %02x %02x"
1108 " %02x %02x %02x %02x"
1113 buf
[i
+4], buf
[i
+5],
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]);
1127 int rndis_register (int (* rndis_control_ack
) (struct net_device
*))
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
);
1144 void rndis_deregister (int configNr
)
1146 DEBUG("%s: \n", __FUNCTION__
);
1148 if (configNr
>= RNDIS_MAX_CONFIGS
) return;
1149 rndis_per_dev_params
[configNr
].used
= 0;
1154 int rndis_set_param_dev (u8 configNr
, struct net_device
*dev
,
1155 struct net_device_stats
*stats
)
1157 DEBUG("%s:\n", __FUNCTION__
);
1158 if (!dev
|| !stats
) return -1;
1159 if (configNr
>= RNDIS_MAX_CONFIGS
) return -1;
1161 rndis_per_dev_params
[configNr
].dev
= dev
;
1162 rndis_per_dev_params
[configNr
].stats
= stats
;
1167 int rndis_set_param_vendor (u8 configNr
, u32 vendorID
, const char *vendorDescr
)
1169 DEBUG("%s:\n", __FUNCTION__
);
1170 if (!vendorDescr
) return -1;
1171 if (configNr
>= RNDIS_MAX_CONFIGS
) return -1;
1173 rndis_per_dev_params
[configNr
].vendorID
= vendorID
;
1174 rndis_per_dev_params
[configNr
].vendorDescr
= vendorDescr
;
1179 int rndis_set_param_medium (u8 configNr
, u32 medium
, u32 speed
)
1181 DEBUG("%s:\n", __FUNCTION__
);
1182 if (configNr
>= RNDIS_MAX_CONFIGS
) return -1;
1184 rndis_per_dev_params
[configNr
].medium
= medium
;
1185 rndis_per_dev_params
[configNr
].speed
= speed
;
1190 void rndis_add_hdr (struct sk_buff
*skb
)
1192 struct rndis_packet_msg_type
*header
;
1196 header
= (void *) skb_push (skb
, sizeof *header
);
1197 memset (header
, 0, sizeof *header
);
1198 header
->MessageType
= __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG
);
1199 header
->MessageLength
= cpu_to_le32(skb
->len
);
1200 header
->DataOffset
= __constant_cpu_to_le32 (36);
1201 header
->DataLength
= cpu_to_le32(skb
->len
- sizeof *header
);
1204 void rndis_free_response (int configNr
, u8
*buf
)
1207 struct list_head
*act
, *tmp
;
1209 list_for_each_safe (act
, tmp
,
1210 &(rndis_per_dev_params
[configNr
].resp_queue
))
1212 r
= list_entry (act
, rndis_resp_t
, list
);
1213 if (r
&& r
->buf
== buf
) {
1214 list_del (&r
->list
);
1220 u8
*rndis_get_next_response (int configNr
, u32
*length
)
1223 struct list_head
*act
, *tmp
;
1225 if (!length
) return NULL
;
1227 list_for_each_safe (act
, tmp
,
1228 &(rndis_per_dev_params
[configNr
].resp_queue
))
1230 r
= list_entry (act
, rndis_resp_t
, list
);
1233 *length
= r
->length
;
1241 static rndis_resp_t
*rndis_add_response (int configNr
, u32 length
)
1245 r
= kmalloc (sizeof (rndis_resp_t
) + length
, GFP_ATOMIC
);
1246 if (!r
) return NULL
;
1248 r
->buf
= (u8
*) (r
+ 1);
1252 list_add_tail (&r
->list
,
1253 &(rndis_per_dev_params
[configNr
].resp_queue
));
1257 int rndis_rm_hdr(struct sk_buff
*skb
)
1259 /* tmp points to a struct rndis_packet_msg_type */
1260 __le32
*tmp
= (void *) skb
->data
;
1262 /* MessageType, MessageLength */
1263 if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG
)
1264 != get_unaligned(tmp
++))
1268 /* DataOffset, DataLength */
1269 if (!skb_pull(skb
, le32_to_cpu(get_unaligned(tmp
++))
1270 + 8 /* offset of DataOffset */))
1272 skb_trim(skb
, le32_to_cpu(get_unaligned(tmp
++)));
1277 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
1279 static int rndis_proc_read (char *page
, char **start
, off_t off
, int count
, int *eof
,
1284 rndis_params
*param
= (rndis_params
*) data
;
1286 out
+= snprintf (out
, count
,
1293 "vendor ID : 0x%08X\n"
1295 param
->confignr
, (param
->used
) ? "y" : "n",
1297 switch (param
->state
) {
1298 case RNDIS_UNINITIALIZED
:
1299 s
= "RNDIS_UNINITIALIZED"; break;
1300 case RNDIS_INITIALIZED
:
1301 s
= "RNDIS_INITIALIZED"; break;
1302 case RNDIS_DATA_INITIALIZED
:
1303 s
= "RNDIS_DATA_INITIALIZED"; break;
1306 (param
->media_state
) ? 0 : param
->speed
*100,
1307 (param
->media_state
) ? "disconnected" : "connected",
1308 param
->vendorID
, param
->vendorDescr
);
1320 *start
= page
+ off
;
1324 static int rndis_proc_write (struct file
*file
, const char __user
*buffer
,
1325 unsigned long count
, void *data
)
1327 rndis_params
*p
= data
;
1329 int i
, fl_speed
= 0;
1331 for (i
= 0; i
< count
; i
++) {
1333 if (get_user(c
, buffer
))
1347 speed
= speed
*10 + c
- '0';
1351 rndis_signal_connect (p
->confignr
);
1355 rndis_signal_disconnect(p
->confignr
);
1358 if (fl_speed
) p
->speed
= speed
;
1359 else DEBUG ("%c is not valid\n", c
);
1369 #define NAME_TEMPLATE "driver/rndis-%03d"
1371 static struct proc_dir_entry
*rndis_connect_state
[RNDIS_MAX_CONFIGS
];
1373 #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
1376 int __init
rndis_init (void)
1380 for (i
= 0; i
< RNDIS_MAX_CONFIGS
; i
++) {
1381 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
1384 sprintf (name
, NAME_TEMPLATE
, i
);
1385 if (!(rndis_connect_state
[i
]
1386 = create_proc_entry (name
, 0660, NULL
)))
1388 DEBUG ("%s :remove entries", __FUNCTION__
);
1390 sprintf (name
, NAME_TEMPLATE
, --i
);
1391 remove_proc_entry (name
, NULL
);
1397 rndis_connect_state
[i
]->nlink
= 1;
1398 rndis_connect_state
[i
]->write_proc
= rndis_proc_write
;
1399 rndis_connect_state
[i
]->read_proc
= rndis_proc_read
;
1400 rndis_connect_state
[i
]->data
= (void *)
1401 (rndis_per_dev_params
+ i
);
1403 rndis_per_dev_params
[i
].confignr
= i
;
1404 rndis_per_dev_params
[i
].used
= 0;
1405 rndis_per_dev_params
[i
].state
= RNDIS_UNINITIALIZED
;
1406 rndis_per_dev_params
[i
].media_state
1407 = NDIS_MEDIA_STATE_DISCONNECTED
;
1408 INIT_LIST_HEAD (&(rndis_per_dev_params
[i
].resp_queue
));
1414 void rndis_exit (void)
1416 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
1420 for (i
= 0; i
< RNDIS_MAX_CONFIGS
; i
++) {
1421 sprintf (name
, NAME_TEMPLATE
, i
);
1422 remove_proc_entry (name
, NULL
);