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>
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).
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.
56 #define DEBUG(str,args...) do { \
58 printk(KERN_DEBUG str , ## args ); \
60 static int rndis_debug = 0;
62 module_param (rndis_debug, bool, 0);
63 MODULE_PARM_DESC (rndis_debug, "enable debugging");
68 #define DEBUG(str,args...) do{}while(0)
71 #define RNDIS_MAX_CONFIGS 1
74 static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
77 static const u32 rndis_driver_version = __constant_cpu_to_le32 (1);
79 /* Function Prototypes */
80 static int rndis_init_response (int configNr, rndis_init_msg_type *buf);
81 static int rndis_query_response (int configNr, rndis_query_msg_type *buf);
82 static int rndis_set_response (int configNr, rndis_set_msg_type *buf);
83 static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf);
84 static int rndis_keepalive_response (int configNr,
85 rndis_keepalive_msg_type *buf);
87 static rndis_resp_t *rndis_add_response (int configNr, u32 length);
91 static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
93 int retval = -ENOTSUPP;
97 rndis_query_cmplt_type *resp;
99 if (!r) return -ENOMEM;
100 resp = (rndis_query_cmplt_type *) r->buf;
102 if (!resp) return -ENOMEM;
106 /* general oids (table 4-1) */
109 case OID_GEN_SUPPORTED_LIST:
110 DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
111 length = sizeof (oid_supported_list);
112 count = length / sizeof (u32);
113 tmp = (u32 *) ((u8 *)resp + 24);
114 for (i = 0; i < count; i++)
115 tmp[i] = cpu_to_le32 (oid_supported_list[i]);
120 case OID_GEN_HARDWARE_STATUS:
121 DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
124 * Hardware must be ready to recieve high level protocols.
126 * reddite ergo quae sunt Caesaris Caesari
127 * et quae sunt Dei Deo!
129 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
134 case OID_GEN_MEDIA_SUPPORTED:
135 DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
137 *((u32 *) resp + 6) = cpu_to_le32 (
138 rndis_per_dev_params [configNr].medium);
143 case OID_GEN_MEDIA_IN_USE:
144 DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
146 /* one medium, one transport... (maybe you do it better) */
147 *((u32 *) resp + 6) = cpu_to_le32 (
148 rndis_per_dev_params [configNr].medium);
153 case OID_GEN_MAXIMUM_FRAME_SIZE:
154 DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
155 if (rndis_per_dev_params [configNr].dev) {
157 *((u32 *) resp + 6) = cpu_to_le32 (
158 rndis_per_dev_params [configNr].dev->mtu);
161 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
167 case OID_GEN_LINK_SPEED:
168 DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
170 if (rndis_per_dev_params [configNr].media_state
171 == NDIS_MEDIA_STATE_DISCONNECTED)
172 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
174 *((u32 *) resp + 6) = cpu_to_le32 (
175 rndis_per_dev_params [configNr].speed);
180 case OID_GEN_TRANSMIT_BLOCK_SIZE:
181 DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
182 if (rndis_per_dev_params [configNr].dev) {
184 *((u32 *) resp + 6) = cpu_to_le32 (
185 rndis_per_dev_params [configNr].dev->mtu);
191 case OID_GEN_RECEIVE_BLOCK_SIZE:
192 DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
193 if (rndis_per_dev_params [configNr].dev) {
195 *((u32 *) resp + 6) = cpu_to_le32 (
196 rndis_per_dev_params [configNr].dev->mtu);
202 case OID_GEN_VENDOR_ID:
203 DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
205 *((u32 *) resp + 6) = cpu_to_le32 (
206 rndis_per_dev_params [configNr].vendorID);
211 case OID_GEN_VENDOR_DESCRIPTION:
212 DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
213 length = strlen (rndis_per_dev_params [configNr].vendorDescr);
214 memcpy ((u8 *) resp + 24,
215 rndis_per_dev_params [configNr].vendorDescr, length);
219 case OID_GEN_VENDOR_DRIVER_VERSION:
220 DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
223 *((u32 *) resp + 6) = rndis_driver_version;
228 case OID_GEN_CURRENT_PACKET_FILTER:
229 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
231 *((u32 *) resp + 6) = cpu_to_le32 (
232 rndis_per_dev_params[configNr].filter);
237 case OID_GEN_MAXIMUM_TOTAL_SIZE:
238 DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
240 *((u32 *) resp + 6) = __constant_cpu_to_le32(
241 RNDIS_MAX_TOTAL_SIZE);
246 case OID_GEN_MEDIA_CONNECT_STATUS:
247 DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
249 *((u32 *) resp + 6) = cpu_to_le32 (
250 rndis_per_dev_params [configNr]
255 case OID_GEN_PHYSICAL_MEDIUM:
256 DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
258 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
262 /* The RNDIS specification is incomplete/wrong. Some versions
263 * of MS-Windows expect OIDs that aren't specified there. Other
264 * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
266 case OID_GEN_MAC_OPTIONS: /* from WinME */
267 DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
269 *((u32 *) resp + 6) = __constant_cpu_to_le32(
270 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
271 | NDIS_MAC_OPTION_FULL_DUPLEX);
275 /* statistics OIDs (table 4-2) */
278 case OID_GEN_XMIT_OK:
279 DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
280 if (rndis_per_dev_params [configNr].stats) {
282 *((u32 *) resp + 6) = cpu_to_le32 (
283 rndis_per_dev_params [configNr].stats->tx_packets -
284 rndis_per_dev_params [configNr].stats->tx_errors -
285 rndis_per_dev_params [configNr].stats->tx_dropped);
288 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
295 DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
296 if (rndis_per_dev_params [configNr].stats) {
298 *((u32 *) resp + 6) = cpu_to_le32 (
299 rndis_per_dev_params [configNr].stats->rx_packets -
300 rndis_per_dev_params [configNr].stats->rx_errors -
301 rndis_per_dev_params [configNr].stats->rx_dropped);
304 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
310 case OID_GEN_XMIT_ERROR:
311 DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
312 if (rndis_per_dev_params [configNr].stats) {
314 *((u32 *) resp + 6) = cpu_to_le32 (
315 rndis_per_dev_params [configNr]
319 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
325 case OID_GEN_RCV_ERROR:
326 DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
327 if (rndis_per_dev_params [configNr].stats) {
328 *((u32 *) resp + 6) = cpu_to_le32 (
329 rndis_per_dev_params [configNr]
333 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
339 case OID_GEN_RCV_NO_BUFFER:
340 DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
341 if (rndis_per_dev_params [configNr].stats) {
342 *((u32 *) resp + 6) = cpu_to_le32 (
343 rndis_per_dev_params [configNr]
347 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
352 #ifdef RNDIS_OPTIONAL_STATS
353 case OID_GEN_DIRECTED_BYTES_XMIT:
354 DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
356 * Aunt Tilly's size of shoes
357 * minus antarctica count of penguins
358 * divided by weight of Alpha Centauri
360 if (rndis_per_dev_params [configNr].stats) {
362 *((u32 *) resp + 6) = cpu_to_le32 (
363 (rndis_per_dev_params [configNr]
365 rndis_per_dev_params [configNr]
367 rndis_per_dev_params [configNr]
372 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
377 case OID_GEN_DIRECTED_FRAMES_XMIT:
378 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
380 if (rndis_per_dev_params [configNr].stats) {
382 *((u32 *) resp + 6) = cpu_to_le32 (
383 (rndis_per_dev_params [configNr]
385 rndis_per_dev_params [configNr]
387 rndis_per_dev_params [configNr]
392 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
397 case OID_GEN_MULTICAST_BYTES_XMIT:
398 DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
399 if (rndis_per_dev_params [configNr].stats) {
400 *((u32 *) resp + 6) = cpu_to_le32 (
401 rndis_per_dev_params [configNr]
402 .stats->multicast*1234);
405 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
410 case OID_GEN_MULTICAST_FRAMES_XMIT:
411 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
412 if (rndis_per_dev_params [configNr].stats) {
413 *((u32 *) resp + 6) = cpu_to_le32 (
414 rndis_per_dev_params [configNr]
418 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
423 case OID_GEN_BROADCAST_BYTES_XMIT:
424 DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
425 if (rndis_per_dev_params [configNr].stats) {
426 *((u32 *) resp + 6) = cpu_to_le32 (
427 rndis_per_dev_params [configNr]
428 .stats->tx_packets/42*255);
431 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
436 case OID_GEN_BROADCAST_FRAMES_XMIT:
437 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
438 if (rndis_per_dev_params [configNr].stats) {
439 *((u32 *) resp + 6) = cpu_to_le32 (
440 rndis_per_dev_params [configNr]
441 .stats->tx_packets/42);
444 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
449 case OID_GEN_DIRECTED_BYTES_RCV:
450 DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
451 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
455 case OID_GEN_DIRECTED_FRAMES_RCV:
456 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
457 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
461 case OID_GEN_MULTICAST_BYTES_RCV:
462 DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
463 if (rndis_per_dev_params [configNr].stats) {
464 *((u32 *) resp + 6) = cpu_to_le32 (
465 rndis_per_dev_params [configNr]
466 .stats->multicast * 1111);
469 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
474 case OID_GEN_MULTICAST_FRAMES_RCV:
475 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
476 if (rndis_per_dev_params [configNr].stats) {
477 *((u32 *) resp + 6) = cpu_to_le32 (
478 rndis_per_dev_params [configNr]
482 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
487 case OID_GEN_BROADCAST_BYTES_RCV:
488 DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
489 if (rndis_per_dev_params [configNr].stats) {
490 *((u32 *) resp + 6) = cpu_to_le32 (
491 rndis_per_dev_params [configNr]
492 .stats->rx_packets/42*255);
495 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
500 case OID_GEN_BROADCAST_FRAMES_RCV:
501 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
502 if (rndis_per_dev_params [configNr].stats) {
503 *((u32 *) resp + 6) = cpu_to_le32 (
504 rndis_per_dev_params [configNr]
505 .stats->rx_packets/42);
508 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
513 case OID_GEN_RCV_CRC_ERROR:
514 DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
515 if (rndis_per_dev_params [configNr].stats) {
516 *((u32 *) resp + 6) = cpu_to_le32 (
517 rndis_per_dev_params [configNr]
518 .stats->rx_crc_errors);
521 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
526 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
527 DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
528 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
531 #endif /* RNDIS_OPTIONAL_STATS */
533 /* ieee802.3 OIDs (table 4-3) */
536 case OID_802_3_PERMANENT_ADDRESS:
537 DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
538 if (rndis_per_dev_params [configNr].dev) {
540 memcpy ((u8 *) resp + 24,
541 rndis_per_dev_params [configNr].host_mac,
545 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
551 case OID_802_3_CURRENT_ADDRESS:
552 DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
553 if (rndis_per_dev_params [configNr].dev) {
555 memcpy ((u8 *) resp + 24,
556 rndis_per_dev_params [configNr].host_mac,
563 case OID_802_3_MULTICAST_LIST:
564 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
566 /* Multicast base address only */
567 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0xE0000000);
572 case OID_802_3_MAXIMUM_LIST_SIZE:
573 DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
575 /* Multicast base address only */
576 *((u32 *) resp + 6) = __constant_cpu_to_le32 (1);
580 case OID_802_3_MAC_OPTIONS:
581 DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
584 /* ieee802.3 statistics OIDs (table 4-4) */
587 case OID_802_3_RCV_ERROR_ALIGNMENT:
588 DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
589 if (rndis_per_dev_params [configNr].stats)
592 *((u32 *) resp + 6) = cpu_to_le32 (
593 rndis_per_dev_params [configNr]
594 .stats->rx_frame_errors);
600 case OID_802_3_XMIT_ONE_COLLISION:
601 DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
603 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
608 case OID_802_3_XMIT_MORE_COLLISIONS:
609 DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
611 *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
615 #ifdef RNDIS_OPTIONAL_STATS
616 case OID_802_3_XMIT_DEFERRED:
617 DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
621 case OID_802_3_XMIT_MAX_COLLISIONS:
622 DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__);
626 case OID_802_3_RCV_OVERRUN:
627 DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__);
631 case OID_802_3_XMIT_UNDERRUN:
632 DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__);
636 case OID_802_3_XMIT_HEARTBEAT_FAILURE:
637 DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__);
641 case OID_802_3_XMIT_TIMES_CRS_LOST:
642 DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__);
646 case OID_802_3_XMIT_LATE_COLLISIONS:
647 DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
650 #endif /* RNDIS_OPTIONAL_STATS */
653 /* power management OIDs (table 4-5) */
654 case OID_PNP_CAPABILITIES:
655 DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__);
657 /* just PM, and remote wakeup on link status change
658 * (not magic packet or pattern match)
660 length = sizeof (struct NDIS_PNP_CAPABILITIES);
661 memset (resp, 0, length);
663 struct NDIS_PNP_CAPABILITIES *caps = (void *) resp;
665 caps->Flags = NDIS_DEVICE_WAKE_UP_ENABLE;
666 caps->WakeUpCapabilities.MinLinkChangeWakeUp
669 /* FIXME then use usb_gadget_wakeup(), and
670 * set USB_CONFIG_ATT_WAKEUP in config desc
675 case OID_PNP_QUERY_POWER:
676 DEBUG("%s: OID_PNP_QUERY_POWER\n", __FUNCTION__);
677 /* sure, handle any power state that maps to USB suspend */
683 printk (KERN_WARNING "%s: query unknown OID 0x%08X\n",
687 resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
688 resp->InformationBufferLength = cpu_to_le32 (length);
689 resp->MessageLength = cpu_to_le32 (24 + length);
690 r->length = 24 + length;
694 static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
697 rndis_set_cmplt_type *resp;
698 int i, retval = -ENOTSUPP;
699 struct rndis_params *params;
703 resp = (rndis_set_cmplt_type *) r->buf;
707 DEBUG("set OID %08x value, len %d:\n", OID, buf_len);
708 for (i = 0; i < buf_len; i += 16) {
710 " %02x %02x %02x %02x"
711 " %02x %02x %02x %02x"
712 " %02x %02x %02x %02x"
713 " %02x %02x %02x %02x"
721 buf[i+10], buf[i+11],
722 buf[i+12], buf [i+13],
723 buf[i+14], buf[i+15]);
727 case OID_GEN_CURRENT_PACKET_FILTER:
728 params = &rndis_per_dev_params [configNr];
731 /* FIXME use these NDIS_PACKET_TYPE_* bitflags to
732 * filter packets in hard_start_xmit()
733 * NDIS_PACKET_TYPE_x == CDC_PACKET_TYPE_x for x in:
734 * PROMISCUOUS, DIRECTED,
735 * MULTICAST, ALL_MULTICAST, BROADCAST
737 params->filter = cpu_to_le32p((u32 *)buf);
738 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
739 __FUNCTION__, params->filter);
741 /* this call has a significant side effect: it's
742 * what makes the packet flow start and stop, like
743 * activating the CDC Ethernet altsetting.
745 if (params->filter) {
746 params->state = RNDIS_DATA_INITIALIZED;
747 netif_carrier_on(params->dev);
748 if (netif_running(params->dev))
749 netif_wake_queue (params->dev);
751 params->state = RNDIS_INITIALIZED;
752 netif_carrier_off (params->dev);
753 netif_stop_queue (params->dev);
757 case OID_802_3_MULTICAST_LIST:
758 /* I think we can ignore this */
759 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
763 case OID_GEN_RNDIS_CONFIG_PARAMETER:
765 struct rndis_config_parameter *param;
766 param = (struct rndis_config_parameter *) buf;
767 DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
769 min(cpu_to_le32(param->ParameterNameLength),80),
770 buf + param->ParameterNameOffset);
777 case OID_PNP_SET_POWER:
778 DEBUG ("OID_PNP_SET_POWER\n");
779 /* sure, handle any power state that maps to USB suspend */
783 case OID_PNP_ENABLE_WAKE_UP:
784 /* always-connected ... */
785 DEBUG ("OID_PNP_ENABLE_WAKE_UP\n");
789 // no PM resume patterns supported (specified where?)
790 // so OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN always fails
794 printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n",
795 __FUNCTION__, OID, buf_len);
805 static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
807 rndis_init_cmplt_type *resp;
810 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
812 r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
814 if (!r) return -ENOMEM;
816 resp = (rndis_init_cmplt_type *) r->buf;
818 if (!resp) return -ENOMEM;
820 resp->MessageType = __constant_cpu_to_le32 (
821 REMOTE_NDIS_INITIALIZE_CMPLT);
822 resp->MessageLength = __constant_cpu_to_le32 (52);
823 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
824 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
825 resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION);
826 resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION);
827 resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);
828 resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3);
829 resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1);
830 resp->MaxTransferSize = cpu_to_le32 (
831 rndis_per_dev_params [configNr].dev->mtu
832 + sizeof (struct ethhdr)
833 + sizeof (struct rndis_packet_msg_type)
835 resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0);
836 resp->AFListOffset = __constant_cpu_to_le32 (0);
837 resp->AFListSize = __constant_cpu_to_le32 (0);
839 if (rndis_per_dev_params [configNr].ack)
840 rndis_per_dev_params [configNr].ack (
841 rndis_per_dev_params [configNr].dev);
846 static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
848 rndis_query_cmplt_type *resp;
851 // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
852 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
855 * we need more memory:
856 * gen_ndis_query_resp expects enough space for
857 * rndis_query_cmplt_type followed by data.
858 * oid_supported_list is the largest data reply
860 r = rndis_add_response (configNr,
861 sizeof (oid_supported_list) + sizeof(rndis_query_cmplt_type));
863 if (!r) return -ENOMEM;
864 resp = (rndis_query_cmplt_type *) r->buf;
866 if (!resp) return -ENOMEM;
868 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
869 resp->MessageLength = __constant_cpu_to_le32 (24);
870 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
872 if (gen_ndis_query_resp (configNr, cpu_to_le32 (buf->OID), r)) {
873 /* OID not supported */
874 resp->Status = __constant_cpu_to_le32 (
875 RNDIS_STATUS_NOT_SUPPORTED);
876 resp->InformationBufferLength = __constant_cpu_to_le32 (0);
877 resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
879 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
881 if (rndis_per_dev_params [configNr].ack)
882 rndis_per_dev_params [configNr].ack (
883 rndis_per_dev_params [configNr].dev);
887 static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
889 u32 BufLength, BufOffset;
890 rndis_set_cmplt_type *resp;
893 r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
895 if (!r) return -ENOMEM;
896 resp = (rndis_set_cmplt_type *) r->buf;
897 if (!resp) return -ENOMEM;
899 BufLength = cpu_to_le32 (buf->InformationBufferLength);
900 BufOffset = cpu_to_le32 (buf->InformationBufferOffset);
903 DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength);
904 DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset);
905 DEBUG("%s: InfoBuffer: ", __FUNCTION__);
907 for (i = 0; i < BufLength; i++) {
908 DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
914 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
915 resp->MessageLength = __constant_cpu_to_le32 (16);
916 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
917 if (gen_ndis_set_resp (configNr, cpu_to_le32 (buf->OID),
918 ((u8 *) buf) + 8 + BufOffset, BufLength, r))
919 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
920 else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
922 if (rndis_per_dev_params [configNr].ack)
923 rndis_per_dev_params [configNr].ack (
924 rndis_per_dev_params [configNr].dev);
929 static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
931 rndis_reset_cmplt_type *resp;
934 r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
936 if (!r) return -ENOMEM;
937 resp = (rndis_reset_cmplt_type *) r->buf;
938 if (!resp) return -ENOMEM;
940 resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
941 resp->MessageLength = __constant_cpu_to_le32 (16);
942 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
943 /* resent information */
944 resp->AddressingReset = __constant_cpu_to_le32 (1);
946 if (rndis_per_dev_params [configNr].ack)
947 rndis_per_dev_params [configNr].ack (
948 rndis_per_dev_params [configNr].dev);
953 static int rndis_keepalive_response (int configNr,
954 rndis_keepalive_msg_type *buf)
956 rndis_keepalive_cmplt_type *resp;
959 /* host "should" check only in RNDIS_DATA_INITIALIZED state */
961 r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
962 resp = (rndis_keepalive_cmplt_type *) r->buf;
963 if (!resp) return -ENOMEM;
965 resp->MessageType = __constant_cpu_to_le32 (
966 REMOTE_NDIS_KEEPALIVE_CMPLT);
967 resp->MessageLength = __constant_cpu_to_le32 (16);
968 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
969 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
971 if (rndis_per_dev_params [configNr].ack)
972 rndis_per_dev_params [configNr].ack (
973 rndis_per_dev_params [configNr].dev);
980 * Device to Host Comunication
982 static int rndis_indicate_status_msg (int configNr, u32 status)
984 rndis_indicate_status_msg_type *resp;
987 if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED)
990 r = rndis_add_response (configNr,
991 sizeof (rndis_indicate_status_msg_type));
992 if (!r) return -ENOMEM;
994 resp = (rndis_indicate_status_msg_type *) r->buf;
995 if (!resp) return -ENOMEM;
997 resp->MessageType = __constant_cpu_to_le32 (
998 REMOTE_NDIS_INDICATE_STATUS_MSG);
999 resp->MessageLength = __constant_cpu_to_le32 (20);
1000 resp->Status = cpu_to_le32 (status);
1001 resp->StatusBufferLength = __constant_cpu_to_le32 (0);
1002 resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
1004 if (rndis_per_dev_params [configNr].ack)
1005 rndis_per_dev_params [configNr].ack (
1006 rndis_per_dev_params [configNr].dev);
1010 int rndis_signal_connect (int configNr)
1012 rndis_per_dev_params [configNr].media_state
1013 = NDIS_MEDIA_STATE_CONNECTED;
1014 return rndis_indicate_status_msg (configNr,
1015 RNDIS_STATUS_MEDIA_CONNECT);
1018 int rndis_signal_disconnect (int configNr)
1020 rndis_per_dev_params [configNr].media_state
1021 = NDIS_MEDIA_STATE_DISCONNECTED;
1022 return rndis_indicate_status_msg (configNr,
1023 RNDIS_STATUS_MEDIA_DISCONNECT);
1026 void rndis_set_host_mac (int configNr, const u8 *addr)
1028 rndis_per_dev_params [configNr].host_mac = addr;
1034 int rndis_msg_parser (u8 configNr, u8 *buf)
1036 u32 MsgType, MsgLength, *tmp;
1037 struct rndis_params *params;
1043 MsgType = cpu_to_le32p(tmp++);
1044 MsgLength = cpu_to_le32p(tmp++);
1046 if (configNr >= RNDIS_MAX_CONFIGS)
1048 params = &rndis_per_dev_params [configNr];
1050 /* For USB: responses may take up to 10 seconds */
1053 case REMOTE_NDIS_INITIALIZE_MSG:
1054 DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
1056 params->state = RNDIS_INITIALIZED;
1057 return rndis_init_response (configNr,
1058 (rndis_init_msg_type *) buf);
1060 case REMOTE_NDIS_HALT_MSG:
1061 DEBUG("%s: REMOTE_NDIS_HALT_MSG\n",
1063 params->state = RNDIS_UNINITIALIZED;
1065 netif_carrier_off (params->dev);
1066 netif_stop_queue (params->dev);
1070 case REMOTE_NDIS_QUERY_MSG:
1071 return rndis_query_response (configNr,
1072 (rndis_query_msg_type *) buf);
1074 case REMOTE_NDIS_SET_MSG:
1075 return rndis_set_response (configNr,
1076 (rndis_set_msg_type *) buf);
1078 case REMOTE_NDIS_RESET_MSG:
1079 DEBUG("%s: REMOTE_NDIS_RESET_MSG\n",
1081 return rndis_reset_response (configNr,
1082 (rndis_reset_msg_type *) buf);
1084 case REMOTE_NDIS_KEEPALIVE_MSG:
1085 /* For USB: host does this every 5 seconds */
1087 DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
1090 return rndis_keepalive_response (configNr,
1091 (rndis_keepalive_msg_type *)
1095 /* At least Windows XP emits some undefined RNDIS messages.
1096 * In one case those messages seemed to relate to the host
1097 * suspending itself.
1099 printk (KERN_WARNING
1100 "%s: unknown RNDIS message 0x%08X len %d\n",
1101 __FUNCTION__ , MsgType, MsgLength);
1104 for (i = 0; i < MsgLength; i += 16) {
1106 " %02x %02x %02x %02x"
1107 " %02x %02x %02x %02x"
1108 " %02x %02x %02x %02x"
1109 " %02x %02x %02x %02x"
1114 buf[i+4], buf [i+5],
1116 buf[i+8], buf [i+9],
1117 buf[i+10], buf[i+11],
1118 buf[i+12], buf [i+13],
1119 buf[i+14], buf[i+15]);
1128 int rndis_register (int (* rndis_control_ack) (struct net_device *))
1132 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1133 if (!rndis_per_dev_params [i].used) {
1134 rndis_per_dev_params [i].used = 1;
1135 rndis_per_dev_params [i].ack = rndis_control_ack;
1136 DEBUG("%s: configNr = %d\n", __FUNCTION__, i);
1145 void rndis_deregister (int configNr)
1147 DEBUG("%s: \n", __FUNCTION__ );
1149 if (configNr >= RNDIS_MAX_CONFIGS) return;
1150 rndis_per_dev_params [configNr].used = 0;
1155 int rndis_set_param_dev (u8 configNr, struct net_device *dev,
1156 struct net_device_stats *stats)
1158 DEBUG("%s:\n", __FUNCTION__ );
1159 if (!dev || !stats) return -1;
1160 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1162 rndis_per_dev_params [configNr].dev = dev;
1163 rndis_per_dev_params [configNr].stats = stats;
1168 int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
1170 DEBUG("%s:\n", __FUNCTION__ );
1171 if (!vendorDescr) return -1;
1172 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1174 rndis_per_dev_params [configNr].vendorID = vendorID;
1175 rndis_per_dev_params [configNr].vendorDescr = vendorDescr;
1180 int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
1182 DEBUG("%s:\n", __FUNCTION__ );
1183 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1185 rndis_per_dev_params [configNr].medium = medium;
1186 rndis_per_dev_params [configNr].speed = speed;
1191 void rndis_add_hdr (struct sk_buff *skb)
1194 skb_push (skb, sizeof (struct rndis_packet_msg_type));
1195 memset (skb->data, 0, sizeof (struct rndis_packet_msg_type));
1196 *((u32 *) skb->data) = __constant_cpu_to_le32 (1);
1197 *((u32 *) skb->data + 1) = cpu_to_le32(skb->len);
1198 *((u32 *) skb->data + 2) = __constant_cpu_to_le32 (36);
1199 *((u32 *) skb->data + 3) = cpu_to_le32(skb->len - 44);
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 (u8 *buf, u32 *length)
1259 u32 i, messageLen, dataOffset, *tmp;
1263 if (!buf || !length) return -1;
1264 if (cpu_to_le32p(tmp++) != 1) return -1;
1266 messageLen = cpu_to_le32p(tmp++);
1267 dataOffset = cpu_to_le32p(tmp++) + 8;
1269 if (messageLen < dataOffset || messageLen > *length) return -1;
1271 for (i = dataOffset; i < messageLen; i++)
1272 buf [i - dataOffset] = buf [i];
1274 *length = messageLen - dataOffset;
1280 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
1282 #include <asm/uaccess.h>
1284 static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
1289 rndis_params *param = (rndis_params *) data;
1291 out += snprintf (out, count,
1298 "vendor ID : 0x%08X\n"
1300 param->confignr, (param->used) ? "y" : "n",
1302 switch (param->state) {
1303 case RNDIS_UNINITIALIZED:
1304 s = "RNDIS_UNINITIALIZED"; break;
1305 case RNDIS_INITIALIZED:
1306 s = "RNDIS_INITIALIZED"; break;
1307 case RNDIS_DATA_INITIALIZED:
1308 s = "RNDIS_DATA_INITIALIZED"; break;
1311 (param->media_state) ? 0 : param->speed*100,
1312 (param->media_state) ? "disconnected" : "connected",
1313 param->vendorID, param->vendorDescr);
1325 *start = page + off;
1329 static int rndis_proc_write (struct file *file, const char __user *buffer,
1330 unsigned long count, void *data)
1332 rndis_params *p = data;
1334 int i, fl_speed = 0;
1336 for (i = 0; i < count; i++) {
1338 if (get_user(c, buffer))
1352 speed = speed*10 + c - '0';
1356 rndis_signal_connect (p->confignr);
1360 rndis_signal_disconnect(p->confignr);
1363 if (fl_speed) p->speed = speed;
1364 else DEBUG ("%c is not valid\n", c);
1374 #define NAME_TEMPLATE "driver/rndis-%03d"
1376 static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
1378 #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
1381 int __init rndis_init (void)
1385 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1386 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
1389 sprintf (name, NAME_TEMPLATE, i);
1390 if (!(rndis_connect_state [i]
1391 = create_proc_entry (name, 0660, NULL)))
1393 DEBUG ("%s :remove entries", __FUNCTION__);
1395 sprintf (name, NAME_TEMPLATE, --i);
1396 remove_proc_entry (name, NULL);
1402 rndis_connect_state [i]->nlink = 1;
1403 rndis_connect_state [i]->write_proc = rndis_proc_write;
1404 rndis_connect_state [i]->read_proc = rndis_proc_read;
1405 rndis_connect_state [i]->data = (void *)
1406 (rndis_per_dev_params + i);
1408 rndis_per_dev_params [i].confignr = i;
1409 rndis_per_dev_params [i].used = 0;
1410 rndis_per_dev_params [i].state = RNDIS_UNINITIALIZED;
1411 rndis_per_dev_params [i].media_state
1412 = NDIS_MEDIA_STATE_DISCONNECTED;
1413 INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue));
1419 void rndis_exit (void)
1421 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
1425 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1426 sprintf (name, NAME_TEMPLATE, i);
1427 remove_proc_entry (name, NULL);