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.
23 #include <linux/config.h>
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/errno.h>
27 #include <linux/version.h>
28 #include <linux/init.h>
29 #include <linux/list.h>
30 #include <linux/proc_fs.h>
31 #include <linux/netdevice.h>
34 #include <asm/byteorder.h>
35 #include <asm/system.h>
40 /* The driver for your USB chip needs to support ep0 OUT to work with
41 * RNDIS, plus the same three descriptors as CDC Ethernet.
43 * Windows hosts need an INF file like Documentation/usb/linux.inf
46 #ifndef __LITTLE_ENDIAN
47 #warning this code is missing all cpu_to_leXX() calls ...
51 #define DEBUG if (rndis_debug) printk
52 static int rndis_debug = 0;
54 MODULE_PARM (rndis_debug, "i");
55 MODULE_PARM_DESC (rndis_debug, "enable debugging");
58 #define DEBUG(str,args...) do{}while(0)
61 #define RNDIS_MAX_CONFIGS 1
63 static struct proc_dir_entry *rndis_connect_dir;
64 static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
66 static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
69 static const u32 rndis_driver_version = __constant_cpu_to_le32 (1);
71 /* Function Prototypes */
72 static int rndis_init_response (int configNr, rndis_init_msg_type *buf);
73 static int rndis_query_response (int configNr, rndis_query_msg_type *buf);
74 static int rndis_set_response (int configNr, rndis_set_msg_type *buf);
75 static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf);
76 static int rndis_keepalive_response (int configNr,
77 rndis_keepalive_msg_type *buf);
79 static rndis_resp_t *rndis_add_response (int configNr, u32 length);
81 /* helper functions */
82 static u32 devFlags2currentFilter (struct net_device *dev)
88 if (dev->flags & IFF_MULTICAST)
89 filter |= NDIS_PACKET_TYPE_MULTICAST;
90 if (dev->flags & IFF_BROADCAST)
91 filter |= NDIS_PACKET_TYPE_BROADCAST;
92 if (dev->flags & IFF_ALLMULTI)
93 filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
94 if (dev->flags & IFF_PROMISC)
95 filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
100 static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev)
102 /* FIXME the filter is supposed to control what gets
103 * forwarded from gadget to host; but dev->flags controls
104 * reporting from host to gadget ...
108 if (currentFilter & NDIS_PACKET_TYPE_MULTICAST)
109 dev->flags |= IFF_MULTICAST;
110 if (currentFilter & NDIS_PACKET_TYPE_BROADCAST)
111 dev->flags |= IFF_BROADCAST;
112 if (currentFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
113 dev->flags |= IFF_ALLMULTI;
114 if (currentFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
115 dev->flags |= IFF_PROMISC;
119 /* FIXME OMITTED OIDs, that RNDIS-on-USB "must" support, include
120 * - power management (OID_PNP_CAPABILITIES, ...)
121 * - network wakeup (OID_PNP_ENABLE_WAKE_UP, ...)
125 static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
127 int retval = -ENOTSUPP;
129 rndis_query_cmplt_type *resp;
131 if (!r) return -ENOMEM;
132 resp = (rndis_query_cmplt_type *) r->buf;
134 if (!resp) return -ENOMEM;
138 case OID_GEN_SUPPORTED_LIST:
139 DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
140 length = sizeof (oid_supported_list);
141 memcpy ((u8 *) resp + 24, oid_supported_list, length);
146 case OID_GEN_HARDWARE_STATUS:
147 DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
150 * Hardware must be ready to recieve high level protocols.
152 * reddite ergo quae sunt Caesaris Caesari
153 * et quae sunt Dei Deo!
155 *((u32 *) resp + 6) = 0;
160 case OID_GEN_MEDIA_SUPPORTED:
161 DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
163 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium;
168 case OID_GEN_MEDIA_IN_USE:
169 DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
171 /* one medium, one transport... (maybe you do it better) */
172 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium;
176 case OID_GEN_MAXIMUM_LOOKAHEAD:
177 DEBUG("%s: OID_GEN_MAXIMUM_LOOKAHEAD\n", __FUNCTION__);
181 case OID_GEN_MAXIMUM_FRAME_SIZE:
182 DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
183 if (rndis_per_dev_params [configNr].dev) {
185 *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
189 *((u32 *) resp + 6) = 0;
195 case OID_GEN_LINK_SPEED:
196 DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
198 if (rndis_per_dev_params [configNr].media_state
199 == NDIS_MEDIA_STATE_DISCONNECTED)
200 *((u32 *) resp + 6) = 0;
202 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].speed;
206 case OID_GEN_TRANSMIT_BUFFER_SPACE:
207 DEBUG("%s: OID_GEN_TRANSMIT_BUFFER_SPACE\n", __FUNCTION__);
209 *((u32 *) resp + 6) = 0;
213 case OID_GEN_RECEIVE_BUFFER_SPACE:
214 DEBUG("%s: OID_GEN_RECEIVE_BUFFER_SPACE\n", __FUNCTION__);
218 case OID_GEN_TRANSMIT_BLOCK_SIZE:
219 DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
220 if (rndis_per_dev_params [configNr].dev) {
222 *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
229 case OID_GEN_RECEIVE_BLOCK_SIZE:
230 DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
231 if (rndis_per_dev_params [configNr].dev) {
233 *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
240 case OID_GEN_VENDOR_ID:
241 DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
243 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].vendorID;
248 case OID_GEN_VENDOR_DESCRIPTION:
249 DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
250 length = strlen (rndis_per_dev_params [configNr].vendorDescr);
251 memcpy ((u8 *) resp + 24,
252 rndis_per_dev_params [configNr].vendorDescr, length);
257 case OID_GEN_CURRENT_PACKET_FILTER:
258 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
260 *((u32 *) resp + 6) = devFlags2currentFilter (
261 rndis_per_dev_params [configNr].dev);
265 case OID_GEN_CURRENT_LOOKAHEAD:
266 DEBUG("%s: OID_GEN_CURRENT_LOOKAHEAD\n", __FUNCTION__);
269 case OID_GEN_DRIVER_VERSION:
270 DEBUG("%s: OID_GEN_DRIVER_VERSION\n", __FUNCTION__);
274 case OID_GEN_MAXIMUM_TOTAL_SIZE:
275 DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
277 *((u32 *) resp + 6) = RNDIS_MAX_TOTAL_SIZE;
281 case OID_GEN_PROTOCOL_OPTIONS:
282 DEBUG("%s: OID_GEN_PROTOCOL_OPTIONS\n", __FUNCTION__);
285 case OID_GEN_MAC_OPTIONS:
286 DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
288 *((u32 *) resp + 6) = NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
289 NDIS_MAC_OPTION_FULL_DUPLEX;
294 case OID_GEN_MEDIA_CONNECT_STATUS:
295 DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
297 *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
302 case OID_GEN_MAXIMUM_SEND_PACKETS:
303 DEBUG("%s: OID_GEN_MAXIMUM_SEND_PACKETS\n", __FUNCTION__);
307 case OID_GEN_VENDOR_DRIVER_VERSION:
308 DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
310 *((u32 *) resp + 6) = rndis_driver_version;
314 case OID_GEN_SUPPORTED_GUIDS:
315 DEBUG("%s: OID_GEN_SUPPORTED_GUIDS\n", __FUNCTION__);
318 case OID_GEN_NETWORK_LAYER_ADDRESSES:
319 DEBUG("%s: OID_GEN_NETWORK_LAYER_ADDRESSES\n", __FUNCTION__);
322 case OID_GEN_TRANSPORT_HEADER_OFFSET:
323 DEBUG("%s: OID_GEN_TRANSPORT_HEADER_OFFSET\n", __FUNCTION__);
326 case OID_GEN_MACHINE_NAME:
327 DEBUG("%s: OID_GEN_MACHINE_NAME\n", __FUNCTION__);
330 case OID_GEN_RNDIS_CONFIG_PARAMETER:
331 DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__);
333 *((u32 *) resp + 6) = 0;
337 case OID_GEN_VLAN_ID:
338 DEBUG("%s: OID_GEN_VLAN_ID\n", __FUNCTION__);
341 case OID_GEN_MEDIA_CAPABILITIES:
342 DEBUG("%s: OID_GEN_MEDIA_CAPABILITIES\n", __FUNCTION__);
345 case OID_GEN_PHYSICAL_MEDIUM:
346 DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
348 *((u32 *) resp + 6) = 0;
353 case OID_GEN_XMIT_OK:
354 DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
355 if (rndis_per_dev_params [configNr].stats) {
357 *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
359 rndis_per_dev_params [configNr].stats->tx_errors -
360 rndis_per_dev_params [configNr].stats->tx_dropped;
363 *((u32 *) resp + 6) = 0;
370 DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
371 if (rndis_per_dev_params [configNr].stats) {
373 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
375 rndis_per_dev_params [configNr].stats->rx_errors -
376 rndis_per_dev_params [configNr].stats->rx_dropped;
379 *((u32 *) resp + 6) = 0;
385 case OID_GEN_XMIT_ERROR:
386 DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
387 if (rndis_per_dev_params [configNr].stats) {
389 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
393 *((u32 *) resp + 6) = 0;
399 case OID_GEN_RCV_ERROR:
400 DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
401 if (rndis_per_dev_params [configNr].stats) {
402 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
406 *((u32 *) resp + 6) = 0;
412 case OID_GEN_RCV_NO_BUFFER:
413 DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
414 if (rndis_per_dev_params [configNr].stats) {
415 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
419 *((u32 *) resp + 6) = 0;
424 case OID_GEN_DIRECTED_BYTES_XMIT:
425 DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
427 * Aunt Tilly's size of shoes
428 * minus antarctica count of penguins
429 * divided by weight of Alpha Centauri
431 if (rndis_per_dev_params [configNr].stats) {
433 *((u32 *) resp + 6) = (rndis_per_dev_params [configNr].
435 rndis_per_dev_params [configNr].stats->tx_errors -
436 rndis_per_dev_params [configNr].stats->tx_dropped)
440 *((u32 *) resp + 6) = 0;
445 case OID_GEN_DIRECTED_FRAMES_XMIT:
446 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
448 if (rndis_per_dev_params [configNr].stats) {
450 *((u32 *) resp + 6) = (rndis_per_dev_params [configNr].
452 rndis_per_dev_params [configNr].stats->tx_errors -
453 rndis_per_dev_params [configNr].stats->tx_dropped)
457 *((u32 *) resp + 6) = 0;
462 case OID_GEN_MULTICAST_BYTES_XMIT:
463 DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
464 if (rndis_per_dev_params [configNr].stats) {
465 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
466 stats->multicast*1234;
469 *((u32 *) resp + 6) = 0;
474 case OID_GEN_MULTICAST_FRAMES_XMIT:
475 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
476 if (rndis_per_dev_params [configNr].stats) {
477 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
481 *((u32 *) resp + 6) = 0;
486 case OID_GEN_BROADCAST_BYTES_XMIT:
487 DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
488 if (rndis_per_dev_params [configNr].stats) {
489 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
490 stats->tx_packets/42*255;
493 *((u32 *) resp + 6) = 0;
498 case OID_GEN_BROADCAST_FRAMES_XMIT:
499 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
500 if (rndis_per_dev_params [configNr].stats) {
501 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
502 stats->tx_packets/42;
505 *((u32 *) resp + 6) = 0;
510 case OID_GEN_DIRECTED_BYTES_RCV:
511 DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
512 *((u32 *) resp + 6) = 0;
516 case OID_GEN_DIRECTED_FRAMES_RCV:
517 DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
518 *((u32 *) resp + 6) = 0;
522 case OID_GEN_MULTICAST_BYTES_RCV:
523 DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
524 if (rndis_per_dev_params [configNr].stats) {
525 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
526 stats->multicast*1111;
529 *((u32 *) resp + 6) = 0;
534 case OID_GEN_MULTICAST_FRAMES_RCV:
535 DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
536 if (rndis_per_dev_params [configNr].stats) {
537 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
541 *((u32 *) resp + 6) = 0;
546 case OID_GEN_BROADCAST_BYTES_RCV:
547 DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
548 if (rndis_per_dev_params [configNr].stats) {
549 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
550 stats->rx_packets/42*255;
553 *((u32 *) resp + 6) = 0;
558 case OID_GEN_BROADCAST_FRAMES_RCV:
559 DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
560 if (rndis_per_dev_params [configNr].stats) {
561 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
562 stats->rx_packets/42;
565 *((u32 *) resp + 6) = 0;
570 case OID_GEN_RCV_CRC_ERROR:
571 DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
572 if (rndis_per_dev_params [configNr].stats) {
573 *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
574 stats->rx_crc_errors;
577 *((u32 *) resp + 6) = 0;
582 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
583 DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
584 *((u32 *) resp + 6) = 0;
588 case OID_GEN_GET_TIME_CAPS:
589 DEBUG("%s: OID_GEN_GET_TIME_CAPS\n", __FUNCTION__);
592 case OID_GEN_GET_NETCARD_TIME:
593 DEBUG("%s: OID_GEN_GET_NETCARD_TIME\n", __FUNCTION__);
596 case OID_GEN_NETCARD_LOAD:
597 DEBUG("%s: OID_GEN_NETCARD_LOAD\n", __FUNCTION__);
600 case OID_GEN_DEVICE_PROFILE:
601 DEBUG("%s: OID_GEN_DEVICE_PROFILE\n", __FUNCTION__);
604 case OID_GEN_INIT_TIME_MS:
605 DEBUG("%s: OID_GEN_INIT_TIME_MS\n", __FUNCTION__);
608 case OID_GEN_RESET_COUNTS:
609 DEBUG("%s: OID_GEN_RESET_COUNTS\n", __FUNCTION__);
612 case OID_GEN_MEDIA_SENSE_COUNTS:
613 DEBUG("%s: OID_GEN_MEDIA_SENSE_COUNTS\n", __FUNCTION__);
616 case OID_GEN_FRIENDLY_NAME:
617 DEBUG("%s: OID_GEN_FRIENDLY_NAME\n", __FUNCTION__);
620 case OID_GEN_MINIPORT_INFO:
621 DEBUG("%s: OID_GEN_MINIPORT_INFO\n", __FUNCTION__);
624 case OID_GEN_RESET_VERIFY_PARAMETERS:
625 DEBUG("%s: OID_GEN_RESET_VERIFY_PARAMETERS\n", __FUNCTION__);
629 case OID_802_3_PERMANENT_ADDRESS:
630 DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
631 if (rndis_per_dev_params [configNr].dev) {
633 memcpy ((u8 *) resp + 24,
634 rndis_per_dev_params [configNr].host_mac,
638 *((u32 *) resp + 6) = 0;
644 case OID_802_3_CURRENT_ADDRESS:
645 DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
646 if (rndis_per_dev_params [configNr].dev) {
648 memcpy ((u8 *) resp + 24,
649 rndis_per_dev_params [configNr].host_mac,
656 case OID_802_3_MULTICAST_LIST:
657 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
659 /* Multicast base address only */
660 *((u32 *) resp + 6) = 0xE0000000;
665 case OID_802_3_MAXIMUM_LIST_SIZE:
666 DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
668 /* Multicast base address only */
669 *((u32 *) resp + 6) = 1;
673 case OID_802_3_MAC_OPTIONS:
674 DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
678 case OID_802_3_RCV_ERROR_ALIGNMENT:
679 DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
680 if (rndis_per_dev_params [configNr].stats)
683 *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
684 .stats->rx_frame_errors;
690 case OID_802_3_XMIT_ONE_COLLISION:
691 DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
693 *((u32 *) resp + 6) = 0;
698 case OID_802_3_XMIT_MORE_COLLISIONS:
699 DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
701 *((u32 *) resp + 6) = 0;
705 case OID_802_3_XMIT_DEFERRED:
706 DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
710 case OID_802_3_XMIT_MAX_COLLISIONS:
711 DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__);
715 case OID_802_3_RCV_OVERRUN:
716 DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__);
720 case OID_802_3_XMIT_UNDERRUN:
721 DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__);
725 case OID_802_3_XMIT_HEARTBEAT_FAILURE:
726 DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__);
730 case OID_802_3_XMIT_TIMES_CRS_LOST:
731 DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__);
735 case OID_802_3_XMIT_LATE_COLLISIONS:
736 DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
740 default: printk (KERN_ERR "%s: unknown OID 0x%08X\n",
744 resp->InformationBufferOffset = 16;
745 resp->InformationBufferLength = length;
746 resp->MessageLength = 24 + length;
747 r->length = 24 + length;
751 static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
754 rndis_set_cmplt_type *resp;
755 int i, retval = -ENOTSUPP;
756 struct rndis_config_parameter *param;
757 struct rndis_params *params;
762 resp = (rndis_set_cmplt_type *) r->buf;
769 case OID_GEN_CURRENT_PACKET_FILTER:
770 DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
771 params = &rndis_per_dev_params [configNr];
772 currentFilter2devFlags(cp[28], params->dev);
775 /* this call has a significant side effect: it's
776 * what makes the packet flow start and stop, like
777 * activating the CDC Ethernet altsetting.
780 params->state = RNDIS_DATA_INITIALIZED;
781 netif_carrier_on(params->dev);
782 if (netif_running(params->dev))
783 netif_wake_queue (params->dev);
785 params->state = RNDIS_INITIALIZED;
786 netif_carrier_off (params->dev);
787 netif_stop_queue (params->dev);
791 case OID_802_3_MULTICAST_LIST:
792 /* I think we can ignore this */
793 DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
797 case OID_GEN_RNDIS_CONFIG_PARAMETER:
798 DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__);
799 param = (struct rndis_config_parameter *) buf;
801 for (i = 0; i < param->ParameterNameLength; i++) {
803 *(buf + param->ParameterNameOffset + i));
811 default: printk (KERN_ERR "%s: unknown OID 0x%08X\n",
822 static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
824 rndis_init_cmplt_type *resp;
827 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
829 r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
831 if (!r) return -ENOMEM;
833 resp = (rndis_init_cmplt_type *) r->buf;
835 if (!resp) return -ENOMEM;
837 resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
838 resp->MessageLength = 52;
839 resp->RequestID = buf->RequestID;
840 resp->Status = RNDIS_STATUS_SUCCESS;
841 resp->MajorVersion = RNDIS_MAJOR_VERSION;
842 resp->MinorVersion = RNDIS_MINOR_VERSION;
843 resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
844 resp->Medium = RNDIS_MEDIUM_802_3;
845 resp->MaxPacketsPerTransfer = 1;
846 resp->MaxTransferSize = rndis_per_dev_params [configNr].dev->mtu
847 + sizeof (struct ethhdr)
848 + sizeof (struct rndis_packet_msg_type)
850 resp->PacketAlignmentFactor = 0;
851 resp->AFListOffset = 0;
852 resp->AFListSize = 0;
854 if (rndis_per_dev_params [configNr].ack)
855 rndis_per_dev_params [configNr].ack (
856 rndis_per_dev_params [configNr].dev);
861 static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
863 rndis_query_cmplt_type *resp;
866 DEBUG("%s: OID = %08X\n", __FUNCTION__, buf->OID);
867 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
870 * we need more memory:
871 * oid_supported_list is the largest answer
873 r = rndis_add_response (configNr, sizeof (oid_supported_list));
875 if (!r) return -ENOMEM;
876 resp = (rndis_query_cmplt_type *) r->buf;
878 if (!resp) return -ENOMEM;
880 resp->MessageType = REMOTE_NDIS_QUERY_CMPLT;
881 resp->MessageLength = 24;
882 resp->RequestID = buf->RequestID;
884 if (gen_ndis_query_resp (configNr, buf->OID, r)) {
885 /* OID not supported */
886 resp->Status = RNDIS_STATUS_NOT_SUPPORTED;
887 resp->InformationBufferLength = 0;
888 resp->InformationBufferOffset = 0;
890 resp->Status = RNDIS_STATUS_SUCCESS;
892 if (rndis_per_dev_params [configNr].ack)
893 rndis_per_dev_params [configNr].ack (
894 rndis_per_dev_params [configNr].dev);
898 static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
900 rndis_set_cmplt_type *resp;
904 r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
906 if (!r) return -ENOMEM;
907 resp = (rndis_set_cmplt_type *) r->buf;
908 if (!resp) return -ENOMEM;
910 DEBUG("%s: Length: %d\n", __FUNCTION__, buf->InformationBufferLength);
911 DEBUG("%s: Offset: %d\n", __FUNCTION__, buf->InformationBufferOffset);
912 DEBUG("%s: InfoBuffer: ", __FUNCTION__);
914 for (i = 0; i < buf->InformationBufferLength; i++) {
915 DEBUG ("%02x ", *(((u8 *) buf) + i + 12 +
916 buf->InformationBufferOffset));
921 resp->MessageType = REMOTE_NDIS_SET_CMPLT;
922 resp->MessageLength = 16;
923 resp->RequestID = buf->RequestID;
924 if (gen_ndis_set_resp (configNr, buf->OID,
926 buf->InformationBufferLength, r))
927 resp->Status = RNDIS_STATUS_NOT_SUPPORTED;
928 else resp->Status = RNDIS_STATUS_SUCCESS;
930 if (rndis_per_dev_params [configNr].ack)
931 rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev);
936 static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
938 rndis_reset_cmplt_type *resp;
941 r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
943 if (!r) return -ENOMEM;
944 resp = (rndis_reset_cmplt_type *) r->buf;
945 if (!resp) return -ENOMEM;
947 resp->MessageType = REMOTE_NDIS_RESET_CMPLT;
948 resp->MessageLength = 16;
949 resp->Status = RNDIS_STATUS_SUCCESS;
950 resp->AddressingReset = 1; /* resent information */
952 if (rndis_per_dev_params [configNr].ack)
953 rndis_per_dev_params [configNr].ack (
954 rndis_per_dev_params [configNr].dev);
959 static int rndis_keepalive_response (int configNr,
960 rndis_keepalive_msg_type *buf)
962 rndis_keepalive_cmplt_type *resp;
965 /* host "should" check only in RNDIS_DATA_INITIALIZED state */
967 r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
968 resp = (rndis_keepalive_cmplt_type *) r->buf;
969 if (!resp) return -ENOMEM;
971 resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
972 resp->MessageLength = 16;
973 resp->RequestID = buf->RequestID;
974 resp->Status = RNDIS_STATUS_SUCCESS;
976 if (rndis_per_dev_params [configNr].ack)
977 rndis_per_dev_params [configNr].ack (
978 rndis_per_dev_params [configNr].dev);
985 * Device to Host Comunication
987 static int rndis_indicate_status_msg (int configNr, u32 status)
989 rndis_indicate_status_msg_type *resp;
992 if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED)
995 r = rndis_add_response (configNr,
996 sizeof (rndis_indicate_status_msg_type));
997 if (!r) return -ENOMEM;
999 resp = (rndis_indicate_status_msg_type *) r->buf;
1000 if (!resp) return -ENOMEM;
1002 resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
1003 resp->MessageLength = 20;
1004 resp->Status = status;
1005 resp->StatusBufferLength = 0;
1006 resp->StatusBufferOffset = 0;
1008 if (rndis_per_dev_params [configNr].ack)
1009 rndis_per_dev_params [configNr].ack (
1010 rndis_per_dev_params [configNr].dev);
1014 int rndis_signal_connect (int configNr)
1016 rndis_per_dev_params [configNr].media_state
1017 = NDIS_MEDIA_STATE_CONNECTED;
1018 return rndis_indicate_status_msg (configNr,
1019 RNDIS_STATUS_MEDIA_CONNECT);
1022 int rndis_signal_disconnect (int configNr)
1024 rndis_per_dev_params [configNr].media_state
1025 = NDIS_MEDIA_STATE_DISCONNECTED;
1026 return rndis_indicate_status_msg (configNr,
1027 RNDIS_STATUS_MEDIA_DISCONNECT);
1030 void rndis_set_host_mac (int configNr, const u8 *addr)
1032 rndis_per_dev_params [configNr].host_mac = addr;
1038 int rndis_msg_parser (u8 configNr, u8 *buf)
1040 u32 MsgType, MsgLength, *tmp;
1041 struct rndis_params *params;
1048 MsgLength = *(tmp + 1);
1050 if (configNr >= RNDIS_MAX_CONFIGS)
1052 params = &rndis_per_dev_params [configNr];
1054 /* For USB: responses may take up to 10 seconds */
1057 case REMOTE_NDIS_INITIALIZE_MSG:
1058 DEBUG(KERN_INFO "%s: REMOTE_NDIS_INITIALIZE_MSG\n",
1060 params->state = RNDIS_INITIALIZED;
1061 return rndis_init_response (configNr,
1062 (rndis_init_msg_type *) buf);
1064 case REMOTE_NDIS_HALT_MSG:
1065 DEBUG(KERN_INFO "%s: REMOTE_NDIS_HALT_MSG\n",
1067 params->state = RNDIS_UNINITIALIZED;
1069 netif_carrier_off (params->dev);
1070 netif_stop_queue (params->dev);
1074 case REMOTE_NDIS_QUERY_MSG:
1075 DEBUG(KERN_INFO "%s: REMOTE_NDIS_QUERY_MSG\n",
1077 return rndis_query_response (configNr,
1078 (rndis_query_msg_type *) buf);
1080 case REMOTE_NDIS_SET_MSG:
1081 DEBUG(KERN_INFO "%s: REMOTE_NDIS_SET_MSG\n",
1083 return rndis_set_response (configNr,
1084 (rndis_set_msg_type *) buf);
1086 case REMOTE_NDIS_RESET_MSG:
1087 DEBUG(KERN_INFO "%s: REMOTE_NDIS_RESET_MSG\n",
1089 return rndis_reset_response (configNr,
1090 (rndis_reset_msg_type *) buf);
1092 case REMOTE_NDIS_KEEPALIVE_MSG:
1093 /* For USB: host does this every 5 seconds */
1094 DEBUG(KERN_INFO "%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
1096 return rndis_keepalive_response (configNr,
1097 (rndis_keepalive_msg_type *)
1101 printk (KERN_ERR "%s: unknown RNDIS Message Type 0x%08X\n",
1102 __FUNCTION__ , MsgType);
1109 int rndis_register (int (* rndis_control_ack) (struct net_device *))
1112 DEBUG("%s: ", __FUNCTION__ );
1114 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1115 if (!rndis_per_dev_params [i].used) {
1116 rndis_per_dev_params [i].used = 1;
1117 rndis_per_dev_params [i].ack = rndis_control_ack;
1118 DEBUG("configNr = %d\n", i);
1127 void rndis_deregister (int configNr)
1129 DEBUG("%s: \n", __FUNCTION__ );
1131 if (configNr >= RNDIS_MAX_CONFIGS) return;
1132 rndis_per_dev_params [configNr].used = 0;
1137 int rndis_set_param_dev (u8 configNr, struct net_device *dev,
1138 struct net_device_stats *stats)
1140 DEBUG("%s:\n", __FUNCTION__ );
1141 if (!dev || !stats) return -1;
1142 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1144 rndis_per_dev_params [configNr].dev = dev;
1145 rndis_per_dev_params [configNr].stats = stats;
1150 int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
1152 DEBUG("%s:\n", __FUNCTION__ );
1153 if (!vendorDescr) return -1;
1154 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1156 rndis_per_dev_params [configNr].vendorID = vendorID;
1157 rndis_per_dev_params [configNr].vendorDescr = vendorDescr;
1162 int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
1164 DEBUG("%s:\n", __FUNCTION__ );
1165 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1167 rndis_per_dev_params [configNr].medium = medium;
1168 rndis_per_dev_params [configNr].speed = speed;
1173 void rndis_add_hdr (struct sk_buff *skb)
1176 skb_push (skb, sizeof (struct rndis_packet_msg_type));
1177 memset (skb->data, 0, sizeof (struct rndis_packet_msg_type));
1178 *((u32 *) skb->data) = 1;
1179 *((u32 *) skb->data + 1) = skb->len;
1180 *((u32 *) skb->data + 2) = 36;
1181 *((u32 *) skb->data + 3) = skb->len - 44;
1186 void rndis_free_response (int configNr, u8 *buf)
1189 struct list_head *act, *tmp;
1191 list_for_each_safe (act, tmp,
1192 &(rndis_per_dev_params [configNr].resp_queue))
1194 r = list_entry (act, rndis_resp_t, list);
1195 if (r && r->buf == buf) {
1196 list_del (&r->list);
1202 u8 *rndis_get_next_response (int configNr, u32 *length)
1205 struct list_head *act, *tmp;
1207 if (!length) return NULL;
1209 list_for_each_safe (act, tmp,
1210 &(rndis_per_dev_params [configNr].resp_queue))
1212 r = list_entry (act, rndis_resp_t, list);
1215 *length = r->length;
1223 static rndis_resp_t *rndis_add_response (int configNr, u32 length)
1227 r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);
1228 if (!r) return NULL;
1230 r->buf = (u8 *) (r + 1);
1234 list_add_tail (&r->list,
1235 &(rndis_per_dev_params [configNr].resp_queue));
1239 int rndis_rm_hdr (u8 *buf, u32 *length)
1241 u32 i, messageLen, dataOffset;
1243 if (!buf || !length) return -1;
1244 if (*((u32 *) buf) != 1) return -1;
1246 messageLen = *((u32 *) buf + 1);
1248 dataOffset = *((u32 *) buf + 2) + 8;
1249 if (messageLen < dataOffset || messageLen > *length) return -1;
1251 for (i = dataOffset; i < messageLen; i++)
1252 buf [i - dataOffset] = buf [i];
1254 *length = messageLen - dataOffset;
1259 int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
1264 rndis_params *param = (rndis_params *) data;
1266 out += snprintf (out, count,
1273 "vendor ID : 0x%08X\n"
1275 param->confignr, (param->used) ? "y" : "n",
1277 switch (param->state) {
1278 case RNDIS_UNINITIALIZED:
1279 s = "RNDIS_UNINITIALIZED"; break;
1280 case RNDIS_INITIALIZED:
1281 s = "RNDIS_INITIALIZED"; break;
1282 case RNDIS_DATA_INITIALIZED:
1283 s = "RNDIS_DATA_INITIALIZED"; break;
1286 (param->media_state) ? 0 : param->speed*100,
1287 (param->media_state) ? "disconnected" : "connected",
1288 param->vendorID, param->vendorDescr);
1300 *start = page + off;
1304 int rndis_proc_write (struct file *file, const char *buffer,
1305 unsigned long count, void *data)
1308 int i, fl_speed = 0;
1310 for (i = 0; i < count; i++) {
1323 speed = speed*10 + *buffer - '0';
1327 rndis_signal_connect (((rndis_params *) data)
1332 rndis_signal_disconnect (((rndis_params *) data)
1336 if (fl_speed) ((rndis_params *) data)->speed = speed;
1337 else DEBUG ("%c is not valid\n", *buffer);
1347 int __init rndis_init (void)
1352 /* FIXME this should probably be /proc/driver/rndis,
1353 * and only if debugging is enabled
1356 if (!(rndis_connect_dir = proc_mkdir ("rndis", NULL))) {
1357 printk (KERN_ERR "%s: couldn't create /proc/rndis entry",
1362 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1363 sprintf (name, "%03d", i);
1364 if (!(rndis_connect_state [i]
1365 = create_proc_entry (name, 0660,
1366 rndis_connect_dir)))
1368 DEBUG ("%s :remove entries", __FUNCTION__);
1369 for (i--; i > 0; i--) {
1370 sprintf (name, "%03d", i);
1371 remove_proc_entry (name, rndis_connect_dir);
1375 remove_proc_entry ("000", rndis_connect_dir);
1376 remove_proc_entry ("rndis", NULL);
1379 rndis_connect_state [i]->nlink = 1;
1380 rndis_connect_state [i]->write_proc = rndis_proc_write;
1381 rndis_connect_state [i]->read_proc = rndis_proc_read;
1382 rndis_connect_state [i]->data = (void *)
1383 (rndis_per_dev_params + i);
1384 rndis_per_dev_params [i].confignr = i;
1385 rndis_per_dev_params [i].used = 0;
1386 rndis_per_dev_params [i].state = RNDIS_UNINITIALIZED;
1387 rndis_per_dev_params [i].media_state
1388 = NDIS_MEDIA_STATE_DISCONNECTED;
1389 INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue));
1395 void rndis_exit (void)
1400 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1401 sprintf (name, "%03d", i);
1402 remove_proc_entry (name, rndis_connect_dir);
1404 remove_proc_entry ("rndis", NULL);