4 * Authors: Benedikt Spranger, Pengutronix
5 * Robert Schwebel, Pengutronix
7 * This software was originally developed in conformance with
8 * Microsoft's Remote NDIS Specification License Agreement.
10 * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
11 * Fixed message length bug in init_response
13 * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
14 * Fixed rndis_rm_hdr length bug.
16 * Copyright (C) 2004 by David Brownell
17 * updates to merge with Linux 2.6, better match RNDIS spec
19 * SPDX-License-Identifier: GPL-2.0
25 #include <linux/types.h>
26 #include <linux/list.h>
27 #include <linux/netdevice.h>
29 #include <asm/byteorder.h>
30 #include <asm/unaligned.h>
31 #include <linux/errno.h>
39 #define ETH_ALEN 6 /* Octets in one ethernet addr */
40 #define ETH_HLEN 14 /* Total octets in header. */
41 #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
42 #define ETH_DATA_LEN 1500 /* Max. octets in payload */
43 #define ETH_FRAME_LEN PKTSIZE_ALIGN /* Max. octets in frame sans FCS */
44 #define ENOTSUPP 524 /* Operation is not supported */
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.
55 #define RNDIS_MAX_CONFIGS 1
57 static rndis_params rndis_per_dev_params
[RNDIS_MAX_CONFIGS
];
60 static const __le32 rndis_driver_version
= __constant_cpu_to_le32(1);
62 /* Function Prototypes */
63 static rndis_resp_t
*rndis_add_response(int configNr
, u32 length
);
67 static const u32 oid_supported_list
[] = {
68 /* the general stuff */
69 OID_GEN_SUPPORTED_LIST
,
70 OID_GEN_HARDWARE_STATUS
,
71 OID_GEN_MEDIA_SUPPORTED
,
73 OID_GEN_MAXIMUM_FRAME_SIZE
,
75 OID_GEN_TRANSMIT_BLOCK_SIZE
,
76 OID_GEN_RECEIVE_BLOCK_SIZE
,
78 OID_GEN_VENDOR_DESCRIPTION
,
79 OID_GEN_VENDOR_DRIVER_VERSION
,
80 OID_GEN_CURRENT_PACKET_FILTER
,
81 OID_GEN_MAXIMUM_TOTAL_SIZE
,
82 OID_GEN_MEDIA_CONNECT_STATUS
,
83 OID_GEN_PHYSICAL_MEDIUM
,
85 OID_GEN_RNDIS_CONFIG_PARAMETER
,
88 /* the statistical stuff */
93 OID_GEN_RCV_NO_BUFFER
,
94 #ifdef RNDIS_OPTIONAL_STATS
95 OID_GEN_DIRECTED_BYTES_XMIT
,
96 OID_GEN_DIRECTED_FRAMES_XMIT
,
97 OID_GEN_MULTICAST_BYTES_XMIT
,
98 OID_GEN_MULTICAST_FRAMES_XMIT
,
99 OID_GEN_BROADCAST_BYTES_XMIT
,
100 OID_GEN_BROADCAST_FRAMES_XMIT
,
101 OID_GEN_DIRECTED_BYTES_RCV
,
102 OID_GEN_DIRECTED_FRAMES_RCV
,
103 OID_GEN_MULTICAST_BYTES_RCV
,
104 OID_GEN_MULTICAST_FRAMES_RCV
,
105 OID_GEN_BROADCAST_BYTES_RCV
,
106 OID_GEN_BROADCAST_FRAMES_RCV
,
107 OID_GEN_RCV_CRC_ERROR
,
108 OID_GEN_TRANSMIT_QUEUE_LENGTH
,
109 #endif /* RNDIS_OPTIONAL_STATS */
111 /* mandatory 802.3 */
112 /* the general stuff */
113 OID_802_3_PERMANENT_ADDRESS
,
114 OID_802_3_CURRENT_ADDRESS
,
115 OID_802_3_MULTICAST_LIST
,
116 OID_802_3_MAC_OPTIONS
,
117 OID_802_3_MAXIMUM_LIST_SIZE
,
119 /* the statistical stuff */
120 OID_802_3_RCV_ERROR_ALIGNMENT
,
121 OID_802_3_XMIT_ONE_COLLISION
,
122 OID_802_3_XMIT_MORE_COLLISIONS
,
123 #ifdef RNDIS_OPTIONAL_STATS
124 OID_802_3_XMIT_DEFERRED
,
125 OID_802_3_XMIT_MAX_COLLISIONS
,
126 OID_802_3_RCV_OVERRUN
,
127 OID_802_3_XMIT_UNDERRUN
,
128 OID_802_3_XMIT_HEARTBEAT_FAILURE
,
129 OID_802_3_XMIT_TIMES_CRS_LOST
,
130 OID_802_3_XMIT_LATE_COLLISIONS
,
131 #endif /* RNDIS_OPTIONAL_STATS */
134 /* PM and wakeup are mandatory for USB: */
136 /* power management */
137 OID_PNP_CAPABILITIES
,
143 OID_PNP_ENABLE_WAKE_UP
,
144 OID_PNP_ADD_WAKE_UP_PATTERN
,
145 OID_PNP_REMOVE_WAKE_UP_PATTERN
,
146 #endif /* RNDIS_WAKEUP */
147 #endif /* RNDIS_PM */
152 static int gen_ndis_query_resp(int configNr
, u32 OID
, u8
*buf
,
153 unsigned buf_len
, rndis_resp_t
*r
)
155 int retval
= -ENOTSUPP
;
156 u32 length
= 4; /* usually */
159 rndis_query_cmplt_type
*resp
;
160 rndis_params
*params
;
164 resp
= (rndis_query_cmplt_type
*) r
->buf
;
169 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
171 debug("query OID %08x value, len %d:\n", OID
, buf_len
);
172 for (i
= 0; i
< buf_len
; i
+= 16) {
173 debug("%03d: %08x %08x %08x %08x\n", i
,
174 get_unaligned_le32(&buf
[i
]),
175 get_unaligned_le32(&buf
[i
+ 4]),
176 get_unaligned_le32(&buf
[i
+ 8]),
177 get_unaligned_le32(&buf
[i
+ 12]));
182 /* response goes here, right after the header */
183 outbuf
= (__le32
*) &resp
[1];
184 resp
->InformationBufferOffset
= __constant_cpu_to_le32(16);
186 params
= &rndis_per_dev_params
[configNr
];
189 /* general oids (table 4-1) */
192 case OID_GEN_SUPPORTED_LIST
:
193 debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__
);
194 length
= sizeof(oid_supported_list
);
195 count
= length
/ sizeof(u32
);
196 for (i
= 0; i
< count
; i
++)
197 outbuf
[i
] = cpu_to_le32(oid_supported_list
[i
]);
202 case OID_GEN_HARDWARE_STATUS
:
203 debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__
);
206 * Hardware must be ready to receive high level protocols.
208 * reddite ergo quae sunt Caesaris Caesari
209 * et quae sunt Dei Deo!
211 *outbuf
= __constant_cpu_to_le32(0);
216 case OID_GEN_MEDIA_SUPPORTED
:
217 debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__
);
218 *outbuf
= cpu_to_le32(params
->medium
);
223 case OID_GEN_MEDIA_IN_USE
:
224 debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__
);
225 /* one medium, one transport... (maybe you do it better) */
226 *outbuf
= cpu_to_le32(params
->medium
);
231 case OID_GEN_MAXIMUM_FRAME_SIZE
:
232 debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__
);
234 *outbuf
= cpu_to_le32(params
->mtu
);
240 case OID_GEN_LINK_SPEED
:
241 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
242 debug("%s: OID_GEN_LINK_SPEED\n", __func__
);
244 if (params
->media_state
== NDIS_MEDIA_STATE_DISCONNECTED
)
245 *outbuf
= __constant_cpu_to_le32(0);
247 *outbuf
= cpu_to_le32(params
->speed
);
252 case OID_GEN_TRANSMIT_BLOCK_SIZE
:
253 debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__
);
255 *outbuf
= cpu_to_le32(params
->mtu
);
261 case OID_GEN_RECEIVE_BLOCK_SIZE
:
262 debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__
);
264 *outbuf
= cpu_to_le32(params
->mtu
);
270 case OID_GEN_VENDOR_ID
:
271 debug("%s: OID_GEN_VENDOR_ID\n", __func__
);
272 *outbuf
= cpu_to_le32(params
->vendorID
);
277 case OID_GEN_VENDOR_DESCRIPTION
:
278 debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__
);
279 length
= strlen(params
->vendorDescr
);
280 memcpy(outbuf
, params
->vendorDescr
, length
);
284 case OID_GEN_VENDOR_DRIVER_VERSION
:
285 debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__
);
287 *outbuf
= rndis_driver_version
;
292 case OID_GEN_CURRENT_PACKET_FILTER
:
293 debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__
);
294 *outbuf
= cpu_to_le32(*params
->filter
);
299 case OID_GEN_MAXIMUM_TOTAL_SIZE
:
300 debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__
);
301 *outbuf
= __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE
);
306 case OID_GEN_MEDIA_CONNECT_STATUS
:
307 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
308 debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__
);
310 *outbuf
= cpu_to_le32(params
->media_state
);
314 case OID_GEN_PHYSICAL_MEDIUM
:
315 debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__
);
316 *outbuf
= __constant_cpu_to_le32(0);
321 * The RNDIS specification is incomplete/wrong. Some versions
322 * of MS-Windows expect OIDs that aren't specified there. Other
323 * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
325 case OID_GEN_MAC_OPTIONS
: /* from WinME */
326 debug("%s: OID_GEN_MAC_OPTIONS\n", __func__
);
327 *outbuf
= __constant_cpu_to_le32(
328 NDIS_MAC_OPTION_RECEIVE_SERIALIZED
329 | NDIS_MAC_OPTION_FULL_DUPLEX
);
333 /* statistics OIDs (table 4-2) */
336 case OID_GEN_XMIT_OK
:
337 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
338 debug("%s: OID_GEN_XMIT_OK\n", __func__
);
341 *outbuf
= cpu_to_le32(
342 params
->stats
->tx_packets
-
343 params
->stats
->tx_errors
-
344 params
->stats
->tx_dropped
);
351 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
352 debug("%s: OID_GEN_RCV_OK\n", __func__
);
355 *outbuf
= cpu_to_le32(
356 params
->stats
->rx_packets
-
357 params
->stats
->rx_errors
-
358 params
->stats
->rx_dropped
);
364 case OID_GEN_XMIT_ERROR
:
365 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
366 debug("%s: OID_GEN_XMIT_ERROR\n", __func__
);
369 *outbuf
= cpu_to_le32(params
->stats
->tx_errors
);
375 case OID_GEN_RCV_ERROR
:
376 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
377 debug("%s: OID_GEN_RCV_ERROR\n", __func__
);
380 *outbuf
= cpu_to_le32(params
->stats
->rx_errors
);
386 case OID_GEN_RCV_NO_BUFFER
:
387 debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__
);
389 *outbuf
= cpu_to_le32(params
->stats
->rx_dropped
);
394 #ifdef RNDIS_OPTIONAL_STATS
395 case OID_GEN_DIRECTED_BYTES_XMIT
:
396 debug("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __func__
);
398 * Aunt Tilly's size of shoes
399 * minus antarctica count of penguins
400 * divided by weight of Alpha Centauri
403 *outbuf
= cpu_to_le32(
404 (params
->stats
->tx_packets
-
405 params
->stats
->tx_errors
-
406 params
->stats
->tx_dropped
)
412 case OID_GEN_DIRECTED_FRAMES_XMIT
:
413 debug("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __func__
);
416 *outbuf
= cpu_to_le32(
417 (params
->stats
->tx_packets
-
418 params
->stats
->tx_errors
-
419 params
->stats
->tx_dropped
)
425 case OID_GEN_MULTICAST_BYTES_XMIT
:
426 debug("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __func__
);
428 *outbuf
= cpu_to_le32(params
->stats
->multicast
* 1234);
433 case OID_GEN_MULTICAST_FRAMES_XMIT
:
434 debug("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __func__
);
436 *outbuf
= cpu_to_le32(params
->stats
->multicast
);
441 case OID_GEN_BROADCAST_BYTES_XMIT
:
442 debug("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __func__
);
444 *outbuf
= cpu_to_le32(params
->stats
->tx_packets
/42*255);
449 case OID_GEN_BROADCAST_FRAMES_XMIT
:
450 debug("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __func__
);
452 *outbuf
= cpu_to_le32(params
->stats
->tx_packets
/ 42);
457 case OID_GEN_DIRECTED_BYTES_RCV
:
458 debug("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __func__
);
459 *outbuf
= __constant_cpu_to_le32(0);
463 case OID_GEN_DIRECTED_FRAMES_RCV
:
464 debug("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __func__
);
465 *outbuf
= __constant_cpu_to_le32(0);
469 case OID_GEN_MULTICAST_BYTES_RCV
:
470 debug("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __func__
);
472 *outbuf
= cpu_to_le32(params
->stats
->multicast
* 1111);
477 case OID_GEN_MULTICAST_FRAMES_RCV
:
478 debug("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __func__
);
480 *outbuf
= cpu_to_le32(params
->stats
->multicast
);
485 case OID_GEN_BROADCAST_BYTES_RCV
:
486 debug("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __func__
);
488 *outbuf
= cpu_to_le32(params
->stats
->rx_packets
/42*255);
493 case OID_GEN_BROADCAST_FRAMES_RCV
:
494 debug("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __func__
);
496 *outbuf
= cpu_to_le32(params
->stats
->rx_packets
/ 42);
501 case OID_GEN_RCV_CRC_ERROR
:
502 debug("%s: OID_GEN_RCV_CRC_ERROR\n", __func__
);
504 *outbuf
= cpu_to_le32(params
->stats
->rx_crc_errors
);
509 case OID_GEN_TRANSMIT_QUEUE_LENGTH
:
510 debug("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __func__
);
511 *outbuf
= __constant_cpu_to_le32(0);
514 #endif /* RNDIS_OPTIONAL_STATS */
516 /* ieee802.3 OIDs (table 4-3) */
519 case OID_802_3_PERMANENT_ADDRESS
:
520 debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__
);
523 memcpy(outbuf
, params
->host_mac
, length
);
529 case OID_802_3_CURRENT_ADDRESS
:
530 debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__
);
533 memcpy(outbuf
, params
->host_mac
, length
);
539 case OID_802_3_MULTICAST_LIST
:
540 debug("%s: OID_802_3_MULTICAST_LIST\n", __func__
);
541 /* Multicast base address only */
542 *outbuf
= __constant_cpu_to_le32(0xE0000000);
547 case OID_802_3_MAXIMUM_LIST_SIZE
:
548 debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__
);
549 /* Multicast base address only */
550 *outbuf
= __constant_cpu_to_le32(1);
554 case OID_802_3_MAC_OPTIONS
:
555 debug("%s: OID_802_3_MAC_OPTIONS\n", __func__
);
558 /* ieee802.3 statistics OIDs (table 4-4) */
561 case OID_802_3_RCV_ERROR_ALIGNMENT
:
562 debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__
);
564 *outbuf
= cpu_to_le32(params
->stats
->rx_frame_errors
);
570 case OID_802_3_XMIT_ONE_COLLISION
:
571 debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__
);
572 *outbuf
= __constant_cpu_to_le32(0);
577 case OID_802_3_XMIT_MORE_COLLISIONS
:
578 debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__
);
579 *outbuf
= __constant_cpu_to_le32(0);
583 #ifdef RNDIS_OPTIONAL_STATS
584 case OID_802_3_XMIT_DEFERRED
:
585 debug("%s: OID_802_3_XMIT_DEFERRED\n", __func__
);
589 case OID_802_3_XMIT_MAX_COLLISIONS
:
590 debug("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __func__
);
594 case OID_802_3_RCV_OVERRUN
:
595 debug("%s: OID_802_3_RCV_OVERRUN\n", __func__
);
599 case OID_802_3_XMIT_UNDERRUN
:
600 debug("%s: OID_802_3_XMIT_UNDERRUN\n", __func__
);
604 case OID_802_3_XMIT_HEARTBEAT_FAILURE
:
605 debug("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __func__
);
609 case OID_802_3_XMIT_TIMES_CRS_LOST
:
610 debug("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __func__
);
614 case OID_802_3_XMIT_LATE_COLLISIONS
:
615 debug("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __func__
);
618 #endif /* RNDIS_OPTIONAL_STATS */
621 /* power management OIDs (table 4-5) */
622 case OID_PNP_CAPABILITIES
:
623 debug("%s: OID_PNP_CAPABILITIES\n", __func__
);
625 /* for now, no wakeup capabilities */
626 length
= sizeof(struct NDIS_PNP_CAPABILITIES
);
627 memset(outbuf
, 0, length
);
630 case OID_PNP_QUERY_POWER
:
631 debug("%s: OID_PNP_QUERY_POWER D%d\n", __func__
,
632 get_unaligned_le32(buf
) - 1);
634 * only suspend is a real power state, and
635 * it can't be entered by OID_PNP_SET_POWER...
643 debug("%s: query unknown OID 0x%08X\n", __func__
, OID
);
648 resp
->InformationBufferLength
= cpu_to_le32(length
);
649 r
->length
= length
+ sizeof *resp
;
650 resp
->MessageLength
= cpu_to_le32(r
->length
);
654 static int gen_ndis_set_resp(u8 configNr
, u32 OID
, u8
*buf
, u32 buf_len
,
657 rndis_set_cmplt_type
*resp
;
658 int retval
= -ENOTSUPP
;
659 struct rndis_params
*params
;
660 #if (defined(DEBUG) && defined(DEBUG_VERBOSE)) || defined(RNDIS_PM)
666 resp
= (rndis_set_cmplt_type
*) r
->buf
;
670 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
672 debug("set OID %08x value, len %d:\n", OID
, buf_len
);
673 for (i
= 0; i
< buf_len
; i
+= 16) {
674 debug("%03d: %08x %08x %08x %08x\n", i
,
675 get_unaligned_le32(&buf
[i
]),
676 get_unaligned_le32(&buf
[i
+ 4]),
677 get_unaligned_le32(&buf
[i
+ 8]),
678 get_unaligned_le32(&buf
[i
+ 12]));
683 params
= &rndis_per_dev_params
[configNr
];
685 case OID_GEN_CURRENT_PACKET_FILTER
:
688 * these NDIS_PACKET_TYPE_* bitflags are shared with
689 * cdc_filter; it's not RNDIS-specific
690 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
691 * PROMISCUOUS, DIRECTED,
692 * MULTICAST, ALL_MULTICAST, BROADCAST
694 *params
->filter
= (u16
) get_unaligned_le32(buf
);
695 debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
696 __func__
, *params
->filter
);
699 * this call has a significant side effect: it's
700 * what makes the packet flow start and stop, like
701 * activating the CDC Ethernet altsetting.
708 params
->state
= RNDIS_DATA_INITIALIZED
;
710 params
->state
= RNDIS_INITIALIZED
;
713 case OID_802_3_MULTICAST_LIST
:
714 /* I think we can ignore this */
715 debug("%s: OID_802_3_MULTICAST_LIST\n", __func__
);
719 case OID_GEN_RNDIS_CONFIG_PARAMETER
:
721 struct rndis_config_parameter
*param
;
722 param
= (struct rndis_config_parameter
*) buf
;
723 debug("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
725 min(cpu_to_le32(param
->ParameterNameLength
), 80),
726 buf
+ param
->ParameterNameOffset
);
733 case OID_PNP_SET_POWER
:
735 * The only real power state is USB suspend, and RNDIS requests
736 * can't enter it; this one isn't really about power. After
737 * resuming, Windows forces a reset, and then SET_POWER D0.
738 * FIXME ... then things go batty; Windows wedges itself.
740 i
= get_unaligned_le32(buf
);
741 debug("%s: OID_PNP_SET_POWER D%d\n", __func__
, i
- 1);
743 case NdisDeviceStateD0
:
744 *params
->filter
= params
->saved_filter
;
745 goto update_linkstate
;
746 case NdisDeviceStateD3
:
747 case NdisDeviceStateD2
:
748 case NdisDeviceStateD1
:
749 params
->saved_filter
= *params
->filter
;
757 * no wakeup support advertised, so wakeup OIDs always fail:
758 * - OID_PNP_ENABLE_WAKE_UP
759 * - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN
763 #endif /* RNDIS_PM */
766 debug("%s: set unknown OID 0x%08X, size %d\n",
767 __func__
, OID
, buf_len
);
777 static int rndis_init_response(int configNr
, rndis_init_msg_type
*buf
)
779 rndis_init_cmplt_type
*resp
;
782 if (!rndis_per_dev_params
[configNr
].dev
)
785 r
= rndis_add_response(configNr
, sizeof(rndis_init_cmplt_type
));
788 resp
= (rndis_init_cmplt_type
*) r
->buf
;
790 resp
->MessageType
= __constant_cpu_to_le32(
791 REMOTE_NDIS_INITIALIZE_CMPLT
);
792 resp
->MessageLength
= __constant_cpu_to_le32(52);
793 resp
->RequestID
= get_unaligned(&buf
->RequestID
); /* Still LE in msg buffer */
794 resp
->Status
= __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS
);
795 resp
->MajorVersion
= __constant_cpu_to_le32(RNDIS_MAJOR_VERSION
);
796 resp
->MinorVersion
= __constant_cpu_to_le32(RNDIS_MINOR_VERSION
);
797 resp
->DeviceFlags
= __constant_cpu_to_le32(RNDIS_DF_CONNECTIONLESS
);
798 resp
->Medium
= __constant_cpu_to_le32(RNDIS_MEDIUM_802_3
);
799 resp
->MaxPacketsPerTransfer
= __constant_cpu_to_le32(1);
800 resp
->MaxTransferSize
= cpu_to_le32(
801 rndis_per_dev_params
[configNr
].mtu
803 + sizeof(struct rndis_packet_msg_type
)
805 resp
->PacketAlignmentFactor
= __constant_cpu_to_le32(0);
806 resp
->AFListOffset
= __constant_cpu_to_le32(0);
807 resp
->AFListSize
= __constant_cpu_to_le32(0);
809 if (rndis_per_dev_params
[configNr
].ack
)
810 rndis_per_dev_params
[configNr
].ack(
811 rndis_per_dev_params
[configNr
].dev
);
816 static int rndis_query_response(int configNr
, rndis_query_msg_type
*buf
)
818 rndis_query_cmplt_type
*resp
;
821 debug("%s: OID = %08X\n", __func__
, get_unaligned_le32(&buf
->OID
));
822 if (!rndis_per_dev_params
[configNr
].dev
)
826 * we need more memory:
827 * gen_ndis_query_resp expects enough space for
828 * rndis_query_cmplt_type followed by data.
829 * oid_supported_list is the largest data reply
831 r
= rndis_add_response(configNr
,
832 sizeof(oid_supported_list
) + sizeof(rndis_query_cmplt_type
));
835 resp
= (rndis_query_cmplt_type
*) r
->buf
;
837 resp
->MessageType
= __constant_cpu_to_le32(REMOTE_NDIS_QUERY_CMPLT
);
838 resp
->RequestID
= get_unaligned(&buf
->RequestID
); /* Still LE in msg buffer */
840 if (gen_ndis_query_resp(configNr
, get_unaligned_le32(&buf
->OID
),
841 get_unaligned_le32(&buf
->InformationBufferOffset
)
843 get_unaligned_le32(&buf
->InformationBufferLength
),
845 /* OID not supported */
846 resp
->Status
= __constant_cpu_to_le32(
847 RNDIS_STATUS_NOT_SUPPORTED
);
848 resp
->MessageLength
= __constant_cpu_to_le32(sizeof *resp
);
849 resp
->InformationBufferLength
= __constant_cpu_to_le32(0);
850 resp
->InformationBufferOffset
= __constant_cpu_to_le32(0);
852 resp
->Status
= __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS
);
854 if (rndis_per_dev_params
[configNr
].ack
)
855 rndis_per_dev_params
[configNr
].ack(
856 rndis_per_dev_params
[configNr
].dev
);
860 static int rndis_set_response(int configNr
, rndis_set_msg_type
*buf
)
862 u32 BufLength
, BufOffset
;
863 rndis_set_cmplt_type
*resp
;
866 r
= rndis_add_response(configNr
, sizeof(rndis_set_cmplt_type
));
869 resp
= (rndis_set_cmplt_type
*) r
->buf
;
871 BufLength
= get_unaligned_le32(&buf
->InformationBufferLength
);
872 BufOffset
= get_unaligned_le32(&buf
->InformationBufferOffset
);
875 debug("%s: Length: %d\n", __func__
, BufLength
);
876 debug("%s: Offset: %d\n", __func__
, BufOffset
);
877 debug("%s: InfoBuffer: ", __func__
);
879 for (i
= 0; i
< BufLength
; i
++)
880 debug("%02x ", *(((u8
*) buf
) + i
+ 8 + BufOffset
));
885 resp
->MessageType
= __constant_cpu_to_le32(REMOTE_NDIS_SET_CMPLT
);
886 resp
->MessageLength
= __constant_cpu_to_le32(16);
887 resp
->RequestID
= get_unaligned(&buf
->RequestID
); /* Still LE in msg buffer */
888 if (gen_ndis_set_resp(configNr
, get_unaligned_le32(&buf
->OID
),
889 ((u8
*) buf
) + 8 + BufOffset
, BufLength
, r
))
890 resp
->Status
= __constant_cpu_to_le32(
891 RNDIS_STATUS_NOT_SUPPORTED
);
893 resp
->Status
= __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS
);
895 if (rndis_per_dev_params
[configNr
].ack
)
896 rndis_per_dev_params
[configNr
].ack(
897 rndis_per_dev_params
[configNr
].dev
);
902 static int rndis_reset_response(int configNr
, rndis_reset_msg_type
*buf
)
904 rndis_reset_cmplt_type
*resp
;
907 r
= rndis_add_response(configNr
, sizeof(rndis_reset_cmplt_type
));
910 resp
= (rndis_reset_cmplt_type
*) r
->buf
;
912 resp
->MessageType
= __constant_cpu_to_le32(REMOTE_NDIS_RESET_CMPLT
);
913 resp
->MessageLength
= __constant_cpu_to_le32(16);
914 resp
->Status
= __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS
);
915 /* resent information */
916 resp
->AddressingReset
= __constant_cpu_to_le32(1);
918 if (rndis_per_dev_params
[configNr
].ack
)
919 rndis_per_dev_params
[configNr
].ack(
920 rndis_per_dev_params
[configNr
].dev
);
925 static int rndis_keepalive_response(int configNr
,
926 rndis_keepalive_msg_type
*buf
)
928 rndis_keepalive_cmplt_type
*resp
;
931 /* host "should" check only in RNDIS_DATA_INITIALIZED state */
933 r
= rndis_add_response(configNr
, sizeof(rndis_keepalive_cmplt_type
));
936 resp
= (rndis_keepalive_cmplt_type
*) r
->buf
;
938 resp
->MessageType
= __constant_cpu_to_le32(
939 REMOTE_NDIS_KEEPALIVE_CMPLT
);
940 resp
->MessageLength
= __constant_cpu_to_le32(16);
941 resp
->RequestID
= get_unaligned(&buf
->RequestID
); /* Still LE in msg buffer */
942 resp
->Status
= __constant_cpu_to_le32(RNDIS_STATUS_SUCCESS
);
944 if (rndis_per_dev_params
[configNr
].ack
)
945 rndis_per_dev_params
[configNr
].ack(
946 rndis_per_dev_params
[configNr
].dev
);
953 * Device to Host Comunication
955 static int rndis_indicate_status_msg(int configNr
, u32 status
)
957 rndis_indicate_status_msg_type
*resp
;
960 if (rndis_per_dev_params
[configNr
].state
== RNDIS_UNINITIALIZED
)
963 r
= rndis_add_response(configNr
,
964 sizeof(rndis_indicate_status_msg_type
));
967 resp
= (rndis_indicate_status_msg_type
*) r
->buf
;
969 resp
->MessageType
= __constant_cpu_to_le32(
970 REMOTE_NDIS_INDICATE_STATUS_MSG
);
971 resp
->MessageLength
= __constant_cpu_to_le32(20);
972 resp
->Status
= cpu_to_le32(status
);
973 resp
->StatusBufferLength
= __constant_cpu_to_le32(0);
974 resp
->StatusBufferOffset
= __constant_cpu_to_le32(0);
976 if (rndis_per_dev_params
[configNr
].ack
)
977 rndis_per_dev_params
[configNr
].ack(
978 rndis_per_dev_params
[configNr
].dev
);
982 int rndis_signal_connect(int configNr
)
984 rndis_per_dev_params
[configNr
].media_state
985 = NDIS_MEDIA_STATE_CONNECTED
;
986 return rndis_indicate_status_msg(configNr
,
987 RNDIS_STATUS_MEDIA_CONNECT
);
990 int rndis_signal_disconnect(int configNr
)
992 rndis_per_dev_params
[configNr
].media_state
993 = NDIS_MEDIA_STATE_DISCONNECTED
;
995 #ifdef RNDIS_COMPLETE_SIGNAL_DISCONNECT
996 return rndis_indicate_status_msg(configNr
,
997 RNDIS_STATUS_MEDIA_DISCONNECT
);
1003 void rndis_uninit(int configNr
)
1008 if (configNr
>= RNDIS_MAX_CONFIGS
)
1010 rndis_per_dev_params
[configNr
].used
= 0;
1011 rndis_per_dev_params
[configNr
].state
= RNDIS_UNINITIALIZED
;
1013 /* drain the response queue */
1014 while ((buf
= rndis_get_next_response(configNr
, &length
)))
1015 rndis_free_response(configNr
, buf
);
1018 void rndis_set_host_mac(int configNr
, const u8
*addr
)
1020 rndis_per_dev_params
[configNr
].host_mac
= addr
;
1023 enum rndis_state
rndis_get_state(int configNr
)
1025 if (configNr
>= RNDIS_MAX_CONFIGS
|| configNr
< 0)
1027 return rndis_per_dev_params
[configNr
].state
;
1033 int rndis_msg_parser(u8 configNr
, u8
*buf
)
1035 u32 MsgType
, MsgLength
;
1037 struct rndis_params
*params
;
1039 debug("%s: configNr = %d, %p\n", __func__
, configNr
, buf
);
1044 tmp
= (__le32
*) buf
;
1045 MsgType
= get_unaligned_le32(tmp
++);
1046 MsgLength
= get_unaligned_le32(tmp
++);
1048 if (configNr
>= RNDIS_MAX_CONFIGS
)
1050 params
= &rndis_per_dev_params
[configNr
];
1053 * NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
1054 * rx/tx statistics and link status, in addition to KEEPALIVE traffic
1055 * and normal HC level polling to see if there's any IN traffic.
1058 /* For USB: responses may take up to 10 seconds */
1060 case REMOTE_NDIS_INITIALIZE_MSG
:
1061 debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n", __func__
);
1062 params
->state
= RNDIS_INITIALIZED
;
1063 return rndis_init_response(configNr
,
1064 (rndis_init_msg_type
*) buf
);
1066 case REMOTE_NDIS_HALT_MSG
:
1067 debug("%s: REMOTE_NDIS_HALT_MSG\n", __func__
);
1068 params
->state
= RNDIS_UNINITIALIZED
;
1071 case REMOTE_NDIS_QUERY_MSG
:
1072 return rndis_query_response(configNr
,
1073 (rndis_query_msg_type
*) buf
);
1075 case REMOTE_NDIS_SET_MSG
:
1076 return rndis_set_response(configNr
,
1077 (rndis_set_msg_type
*) buf
);
1079 case REMOTE_NDIS_RESET_MSG
:
1080 debug("%s: REMOTE_NDIS_RESET_MSG\n", __func__
);
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 */
1086 #if defined(DEBUG) && defined(DEBUG_VERBOSE)
1087 debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", __func__
);
1089 return rndis_keepalive_response(configNr
,
1090 (rndis_keepalive_msg_type
*) buf
);
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 debug("%s: unknown RNDIS message 0x%08X len %d\n",
1099 __func__
, MsgType
, MsgLength
);
1102 for (i
= 0; i
< MsgLength
; i
+= 16) {
1104 " %02x %02x %02x %02x"
1105 " %02x %02x %02x %02x"
1106 " %02x %02x %02x %02x"
1107 " %02x %02x %02x %02x"
1115 buf
[i
+10], buf
[i
+11],
1116 buf
[i
+12], buf
[i
+13],
1117 buf
[i
+14], buf
[i
+15]);
1126 int rndis_register(int (*rndis_control_ack
)(struct eth_device
*))
1130 for (i
= 0; i
< RNDIS_MAX_CONFIGS
; i
++) {
1131 if (!rndis_per_dev_params
[i
].used
) {
1132 rndis_per_dev_params
[i
].used
= 1;
1133 rndis_per_dev_params
[i
].ack
= rndis_control_ack
;
1134 debug("%s: configNr = %d\n", __func__
, i
);
1138 debug("%s failed\n", __func__
);
1143 void rndis_deregister(int configNr
)
1145 debug("%s: configNr = %d\n", __func__
, configNr
);
1147 if (configNr
>= RNDIS_MAX_CONFIGS
)
1149 rndis_per_dev_params
[configNr
].used
= 0;
1154 int rndis_set_param_dev(u8 configNr
, struct eth_device
*dev
, int mtu
,
1155 struct net_device_stats
*stats
, u16
*cdc_filter
)
1157 debug("%s: configNr = %d\n", __func__
, configNr
);
1160 if (configNr
>= RNDIS_MAX_CONFIGS
)
1163 rndis_per_dev_params
[configNr
].dev
= dev
;
1164 rndis_per_dev_params
[configNr
].stats
= stats
;
1165 rndis_per_dev_params
[configNr
].mtu
= mtu
;
1166 rndis_per_dev_params
[configNr
].filter
= cdc_filter
;
1171 int rndis_set_param_vendor(u8 configNr
, u32 vendorID
, const char *vendorDescr
)
1173 debug("%s: configNr = %d\n", __func__
, configNr
);
1176 if (configNr
>= RNDIS_MAX_CONFIGS
)
1179 rndis_per_dev_params
[configNr
].vendorID
= vendorID
;
1180 rndis_per_dev_params
[configNr
].vendorDescr
= vendorDescr
;
1185 int rndis_set_param_medium(u8 configNr
, u32 medium
, u32 speed
)
1187 debug("%s: configNr = %d, %u %u\n", __func__
, configNr
, medium
, speed
);
1188 if (configNr
>= RNDIS_MAX_CONFIGS
)
1191 rndis_per_dev_params
[configNr
].medium
= medium
;
1192 rndis_per_dev_params
[configNr
].speed
= speed
;
1197 void rndis_add_hdr(void *buf
, int length
)
1199 struct rndis_packet_msg_type
*header
;
1202 memset(header
, 0, sizeof *header
);
1203 header
->MessageType
= __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG
);
1204 header
->MessageLength
= cpu_to_le32(length
+ sizeof *header
);
1205 header
->DataOffset
= __constant_cpu_to_le32(36);
1206 header
->DataLength
= cpu_to_le32(length
);
1209 void rndis_free_response(int configNr
, u8
*buf
)
1212 struct list_head
*act
, *tmp
;
1214 list_for_each_safe(act
, tmp
,
1215 &(rndis_per_dev_params
[configNr
].resp_queue
))
1217 r
= list_entry(act
, rndis_resp_t
, list
);
1218 if (r
&& r
->buf
== buf
) {
1225 u8
*rndis_get_next_response(int configNr
, u32
*length
)
1228 struct list_head
*act
, *tmp
;
1233 list_for_each_safe(act
, tmp
,
1234 &(rndis_per_dev_params
[configNr
].resp_queue
))
1236 r
= list_entry(act
, rndis_resp_t
, list
);
1239 *length
= r
->length
;
1247 static rndis_resp_t
*rndis_add_response(int configNr
, u32 length
)
1251 /* NOTE: this gets copied into ether.c USB_BUFSIZ bytes ... */
1252 r
= malloc(sizeof(rndis_resp_t
) + length
);
1256 r
->buf
= (u8
*) (r
+ 1);
1260 list_add_tail(&r
->list
,
1261 &(rndis_per_dev_params
[configNr
].resp_queue
));
1265 int rndis_rm_hdr(void *buf
, int length
)
1267 /* tmp points to a struct rndis_packet_msg_type */
1271 /* MessageType, MessageLength */
1272 if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG
)
1273 != get_unaligned(tmp
++))
1277 /* DataOffset, DataLength */
1278 offs
= get_unaligned_le32(tmp
++) + 8 /* offset of DataOffset */;
1279 if (offs
!= sizeof(struct rndis_packet_msg_type
))
1280 debug("%s: unexpected DataOffset: %d\n", __func__
, offs
);
1284 len
= get_unaligned_le32(tmp
++);
1285 if (len
+ sizeof(struct rndis_packet_msg_type
) != length
)
1286 debug("%s: unexpected DataLength: %d, packet length=%d\n",
1287 __func__
, len
, length
);
1289 memmove(buf
, buf
+ offs
, len
);
1294 int rndis_init(void)
1298 for (i
= 0; i
< RNDIS_MAX_CONFIGS
; i
++) {
1299 rndis_per_dev_params
[i
].confignr
= i
;
1300 rndis_per_dev_params
[i
].used
= 0;
1301 rndis_per_dev_params
[i
].state
= RNDIS_UNINITIALIZED
;
1302 rndis_per_dev_params
[i
].media_state
1303 = NDIS_MEDIA_STATE_DISCONNECTED
;
1304 INIT_LIST_HEAD(&(rndis_per_dev_params
[i
].resp_queue
));
1310 void rndis_exit(void)