• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/usb/gadget/
1/*
2 * RNDIS MSG parser
3 *
4 * Authors:	Benedikt Spranger, Pengutronix
5 *		Robert Schwebel, Pengutronix
6 *
7 *              This program is free software; you can redistribute it and/or
8 *              modify it under the terms of the GNU General Public License
9 *              version 2, as published by the Free Software Foundation.
10 *
11 *		This software was originally developed in conformance with
12 *		Microsoft's Remote NDIS Specification License Agreement.
13 *
14 * 03/12/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
15 *		Fixed message length bug in init_response
16 *
17 * 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
18 *		Fixed rndis_rm_hdr length bug.
19 *
20 * Copyright (C) 2004 by David Brownell
21 *		updates to merge with Linux 2.6, better match RNDIS spec
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/kernel.h>
27#include <linux/errno.h>
28#include <linux/init.h>
29#include <linux/list.h>
30#include <linux/proc_fs.h>
31#include <linux/slab.h>
32#include <linux/seq_file.h>
33#include <linux/netdevice.h>
34
35#include <asm/io.h>
36#include <asm/byteorder.h>
37#include <asm/system.h>
38#include <asm/unaligned.h>
39
40
41#undef	VERBOSE_DEBUG
42
43#include "rndis.h"
44
45
46/* The driver for your USB chip needs to support ep0 OUT to work with
47 * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
48 *
49 * Windows hosts need an INF file like Documentation/usb/linux.inf
50 * and will be happier if you provide the host_addr module parameter.
51 */
52
53#define rndis_debug		0
54
55#define RNDIS_MAX_CONFIGS	1
56
57
58static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
59
60/* Driver Version */
61static const __le32 rndis_driver_version = cpu_to_le32 (1);
62
63/* Function Prototypes */
64static rndis_resp_t *rndis_add_response (int configNr, u32 length);
65
66
67/* supported OIDs */
68static const u32 oid_supported_list [] =
69{
70	/* the general stuff */
71	OID_GEN_SUPPORTED_LIST,
72	OID_GEN_HARDWARE_STATUS,
73	OID_GEN_MEDIA_SUPPORTED,
74	OID_GEN_MEDIA_IN_USE,
75	OID_GEN_MAXIMUM_FRAME_SIZE,
76	OID_GEN_LINK_SPEED,
77	OID_GEN_TRANSMIT_BLOCK_SIZE,
78	OID_GEN_RECEIVE_BLOCK_SIZE,
79	OID_GEN_VENDOR_ID,
80	OID_GEN_VENDOR_DESCRIPTION,
81	OID_GEN_VENDOR_DRIVER_VERSION,
82	OID_GEN_CURRENT_PACKET_FILTER,
83	OID_GEN_MAXIMUM_TOTAL_SIZE,
84	OID_GEN_MEDIA_CONNECT_STATUS,
85	OID_GEN_PHYSICAL_MEDIUM,
86
87	/* the statistical stuff */
88	OID_GEN_XMIT_OK,
89	OID_GEN_RCV_OK,
90	OID_GEN_XMIT_ERROR,
91	OID_GEN_RCV_ERROR,
92	OID_GEN_RCV_NO_BUFFER,
93#ifdef	RNDIS_OPTIONAL_STATS
94	OID_GEN_DIRECTED_BYTES_XMIT,
95	OID_GEN_DIRECTED_FRAMES_XMIT,
96	OID_GEN_MULTICAST_BYTES_XMIT,
97	OID_GEN_MULTICAST_FRAMES_XMIT,
98	OID_GEN_BROADCAST_BYTES_XMIT,
99	OID_GEN_BROADCAST_FRAMES_XMIT,
100	OID_GEN_DIRECTED_BYTES_RCV,
101	OID_GEN_DIRECTED_FRAMES_RCV,
102	OID_GEN_MULTICAST_BYTES_RCV,
103	OID_GEN_MULTICAST_FRAMES_RCV,
104	OID_GEN_BROADCAST_BYTES_RCV,
105	OID_GEN_BROADCAST_FRAMES_RCV,
106	OID_GEN_RCV_CRC_ERROR,
107	OID_GEN_TRANSMIT_QUEUE_LENGTH,
108#endif	/* RNDIS_OPTIONAL_STATS */
109
110	/* mandatory 802.3 */
111	/* the general stuff */
112	OID_802_3_PERMANENT_ADDRESS,
113	OID_802_3_CURRENT_ADDRESS,
114	OID_802_3_MULTICAST_LIST,
115	OID_802_3_MAC_OPTIONS,
116	OID_802_3_MAXIMUM_LIST_SIZE,
117
118	/* the statistical stuff */
119	OID_802_3_RCV_ERROR_ALIGNMENT,
120	OID_802_3_XMIT_ONE_COLLISION,
121	OID_802_3_XMIT_MORE_COLLISIONS,
122#ifdef	RNDIS_OPTIONAL_STATS
123	OID_802_3_XMIT_DEFERRED,
124	OID_802_3_XMIT_MAX_COLLISIONS,
125	OID_802_3_RCV_OVERRUN,
126	OID_802_3_XMIT_UNDERRUN,
127	OID_802_3_XMIT_HEARTBEAT_FAILURE,
128	OID_802_3_XMIT_TIMES_CRS_LOST,
129	OID_802_3_XMIT_LATE_COLLISIONS,
130#endif	/* RNDIS_OPTIONAL_STATS */
131
132#ifdef	RNDIS_PM
133
134	/* power management */
135	OID_PNP_CAPABILITIES,
136	OID_PNP_QUERY_POWER,
137	OID_PNP_SET_POWER,
138
139#ifdef	RNDIS_WAKEUP
140	/* wake up host */
141	OID_PNP_ENABLE_WAKE_UP,
142	OID_PNP_ADD_WAKE_UP_PATTERN,
143	OID_PNP_REMOVE_WAKE_UP_PATTERN,
144#endif	/* RNDIS_WAKEUP */
145#endif	/* RNDIS_PM */
146};
147
148
149/* NDIS Functions */
150static int
151gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
152		rndis_resp_t *r)
153{
154	int			retval = -ENOTSUPP;
155	u32			length = 4;	/* usually */
156	__le32			*outbuf;
157	int			i, count;
158	rndis_query_cmplt_type	*resp;
159	struct net_device	*net;
160	struct rtnl_link_stats64 temp;
161	const struct rtnl_link_stats64 *stats;
162
163	if (!r) return -ENOMEM;
164	resp = (rndis_query_cmplt_type *) r->buf;
165
166	if (!resp) return -ENOMEM;
167
168	if (buf_len && rndis_debug > 1) {
169		pr_debug("query OID %08x value, len %d:\n", OID, buf_len);
170		for (i = 0; i < buf_len; i += 16) {
171			pr_debug("%03d: %08x %08x %08x %08x\n", i,
172				get_unaligned_le32(&buf[i]),
173				get_unaligned_le32(&buf[i + 4]),
174				get_unaligned_le32(&buf[i + 8]),
175				get_unaligned_le32(&buf[i + 12]));
176		}
177	}
178
179	/* response goes here, right after the header */
180	outbuf = (__le32 *) &resp[1];
181	resp->InformationBufferOffset = cpu_to_le32 (16);
182
183	net = rndis_per_dev_params[configNr].dev;
184	stats = dev_get_stats(net, &temp);
185
186	switch (OID) {
187
188	/* general oids (table 4-1) */
189
190	/* mandatory */
191	case OID_GEN_SUPPORTED_LIST:
192		pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
193		length = sizeof (oid_supported_list);
194		count  = length / sizeof (u32);
195		for (i = 0; i < count; i++)
196			outbuf[i] = cpu_to_le32 (oid_supported_list[i]);
197		retval = 0;
198		break;
199
200	/* mandatory */
201	case OID_GEN_HARDWARE_STATUS:
202		pr_debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
203		/* Bogus question!
204		 * Hardware must be ready to receive high level protocols.
205		 * BTW:
206		 * reddite ergo quae sunt Caesaris Caesari
207		 * et quae sunt Dei Deo!
208		 */
209		*outbuf = cpu_to_le32 (0);
210		retval = 0;
211		break;
212
213	/* mandatory */
214	case OID_GEN_MEDIA_SUPPORTED:
215		pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
216		*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
217		retval = 0;
218		break;
219
220	/* mandatory */
221	case OID_GEN_MEDIA_IN_USE:
222		pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
223		/* one medium, one transport... (maybe you do it better) */
224		*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
225		retval = 0;
226		break;
227
228	/* mandatory */
229	case OID_GEN_MAXIMUM_FRAME_SIZE:
230		pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
231		if (rndis_per_dev_params [configNr].dev) {
232			*outbuf = cpu_to_le32 (
233				rndis_per_dev_params [configNr].dev->mtu);
234			retval = 0;
235		}
236		break;
237
238	/* mandatory */
239	case OID_GEN_LINK_SPEED:
240		if (rndis_debug > 1)
241			pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__);
242		if (rndis_per_dev_params [configNr].media_state
243				== NDIS_MEDIA_STATE_DISCONNECTED)
244			*outbuf = cpu_to_le32 (0);
245		else
246			*outbuf = cpu_to_le32 (
247				rndis_per_dev_params [configNr].speed);
248		retval = 0;
249		break;
250
251	/* mandatory */
252	case OID_GEN_TRANSMIT_BLOCK_SIZE:
253		pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
254		if (rndis_per_dev_params [configNr].dev) {
255			*outbuf = cpu_to_le32 (
256				rndis_per_dev_params [configNr].dev->mtu);
257			retval = 0;
258		}
259		break;
260
261	/* mandatory */
262	case OID_GEN_RECEIVE_BLOCK_SIZE:
263		pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
264		if (rndis_per_dev_params [configNr].dev) {
265			*outbuf = cpu_to_le32 (
266				rndis_per_dev_params [configNr].dev->mtu);
267			retval = 0;
268		}
269		break;
270
271	/* mandatory */
272	case OID_GEN_VENDOR_ID:
273		pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__);
274		*outbuf = cpu_to_le32 (
275			rndis_per_dev_params [configNr].vendorID);
276		retval = 0;
277		break;
278
279	/* mandatory */
280	case OID_GEN_VENDOR_DESCRIPTION:
281		pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
282		if ( rndis_per_dev_params [configNr].vendorDescr ) {
283			length = strlen (rndis_per_dev_params [configNr].vendorDescr);
284			memcpy (outbuf,
285				rndis_per_dev_params [configNr].vendorDescr, length);
286		} else {
287			outbuf[0] = 0;
288		}
289		retval = 0;
290		break;
291
292	case OID_GEN_VENDOR_DRIVER_VERSION:
293		pr_debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
294		/* Created as LE */
295		*outbuf = rndis_driver_version;
296		retval = 0;
297		break;
298
299	/* mandatory */
300	case OID_GEN_CURRENT_PACKET_FILTER:
301		pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
302		*outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
303		retval = 0;
304		break;
305
306	/* mandatory */
307	case OID_GEN_MAXIMUM_TOTAL_SIZE:
308		pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
309		*outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
310		retval = 0;
311		break;
312
313	/* mandatory */
314	case OID_GEN_MEDIA_CONNECT_STATUS:
315		if (rndis_debug > 1)
316			pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
317		*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
318						.media_state);
319		retval = 0;
320		break;
321
322	case OID_GEN_PHYSICAL_MEDIUM:
323		pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
324		*outbuf = cpu_to_le32 (0);
325		retval = 0;
326		break;
327
328	/* The RNDIS specification is incomplete/wrong.   Some versions
329	 * of MS-Windows expect OIDs that aren't specified there.  Other
330	 * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
331	 */
332	case OID_GEN_MAC_OPTIONS:		/* from WinME */
333		pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__);
334		*outbuf = cpu_to_le32(
335			  NDIS_MAC_OPTION_RECEIVE_SERIALIZED
336			| NDIS_MAC_OPTION_FULL_DUPLEX);
337		retval = 0;
338		break;
339
340	/* statistics OIDs (table 4-2) */
341
342	/* mandatory */
343	case OID_GEN_XMIT_OK:
344		if (rndis_debug > 1)
345			pr_debug("%s: OID_GEN_XMIT_OK\n", __func__);
346		if (stats) {
347			*outbuf = cpu_to_le32(stats->tx_packets
348				- stats->tx_errors - stats->tx_dropped);
349			retval = 0;
350		}
351		break;
352
353	/* mandatory */
354	case OID_GEN_RCV_OK:
355		if (rndis_debug > 1)
356			pr_debug("%s: OID_GEN_RCV_OK\n", __func__);
357		if (stats) {
358			*outbuf = cpu_to_le32(stats->rx_packets
359				- stats->rx_errors - stats->rx_dropped);
360			retval = 0;
361		}
362		break;
363
364	/* mandatory */
365	case OID_GEN_XMIT_ERROR:
366		if (rndis_debug > 1)
367			pr_debug("%s: OID_GEN_XMIT_ERROR\n", __func__);
368		if (stats) {
369			*outbuf = cpu_to_le32(stats->tx_errors);
370			retval = 0;
371		}
372		break;
373
374	/* mandatory */
375	case OID_GEN_RCV_ERROR:
376		if (rndis_debug > 1)
377			pr_debug("%s: OID_GEN_RCV_ERROR\n", __func__);
378		if (stats) {
379			*outbuf = cpu_to_le32(stats->rx_errors);
380			retval = 0;
381		}
382		break;
383
384	/* mandatory */
385	case OID_GEN_RCV_NO_BUFFER:
386		pr_debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
387		if (stats) {
388			*outbuf = cpu_to_le32(stats->rx_dropped);
389			retval = 0;
390		}
391		break;
392
393	/* ieee802.3 OIDs (table 4-3) */
394
395	/* mandatory */
396	case OID_802_3_PERMANENT_ADDRESS:
397		pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
398		if (rndis_per_dev_params [configNr].dev) {
399			length = ETH_ALEN;
400			memcpy (outbuf,
401				rndis_per_dev_params [configNr].host_mac,
402				length);
403			retval = 0;
404		}
405		break;
406
407	/* mandatory */
408	case OID_802_3_CURRENT_ADDRESS:
409		pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
410		if (rndis_per_dev_params [configNr].dev) {
411			length = ETH_ALEN;
412			memcpy (outbuf,
413				rndis_per_dev_params [configNr].host_mac,
414				length);
415			retval = 0;
416		}
417		break;
418
419	/* mandatory */
420	case OID_802_3_MULTICAST_LIST:
421		pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
422		/* Multicast base address only */
423		*outbuf = cpu_to_le32 (0xE0000000);
424		retval = 0;
425		break;
426
427	/* mandatory */
428	case OID_802_3_MAXIMUM_LIST_SIZE:
429		pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
430		/* Multicast base address only */
431		*outbuf = cpu_to_le32 (1);
432		retval = 0;
433		break;
434
435	case OID_802_3_MAC_OPTIONS:
436		pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
437		*outbuf = cpu_to_le32(0);
438		retval = 0;
439		break;
440
441	/* ieee802.3 statistics OIDs (table 4-4) */
442
443	/* mandatory */
444	case OID_802_3_RCV_ERROR_ALIGNMENT:
445		pr_debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
446		if (stats) {
447			*outbuf = cpu_to_le32(stats->rx_frame_errors);
448			retval = 0;
449		}
450		break;
451
452	/* mandatory */
453	case OID_802_3_XMIT_ONE_COLLISION:
454		pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
455		*outbuf = cpu_to_le32 (0);
456		retval = 0;
457		break;
458
459	/* mandatory */
460	case OID_802_3_XMIT_MORE_COLLISIONS:
461		pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
462		*outbuf = cpu_to_le32 (0);
463		retval = 0;
464		break;
465
466	default:
467		pr_warning("%s: query unknown OID 0x%08X\n",
468			 __func__, OID);
469	}
470	if (retval < 0)
471		length = 0;
472
473	resp->InformationBufferLength = cpu_to_le32 (length);
474	r->length = length + sizeof *resp;
475	resp->MessageLength = cpu_to_le32 (r->length);
476	return retval;
477}
478
479static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
480			rndis_resp_t *r)
481{
482	rndis_set_cmplt_type		*resp;
483	int				i, retval = -ENOTSUPP;
484	struct rndis_params		*params;
485
486	if (!r)
487		return -ENOMEM;
488	resp = (rndis_set_cmplt_type *) r->buf;
489	if (!resp)
490		return -ENOMEM;
491
492	if (buf_len && rndis_debug > 1) {
493		pr_debug("set OID %08x value, len %d:\n", OID, buf_len);
494		for (i = 0; i < buf_len; i += 16) {
495			pr_debug("%03d: %08x %08x %08x %08x\n", i,
496				get_unaligned_le32(&buf[i]),
497				get_unaligned_le32(&buf[i + 4]),
498				get_unaligned_le32(&buf[i + 8]),
499				get_unaligned_le32(&buf[i + 12]));
500		}
501	}
502
503	params = &rndis_per_dev_params [configNr];
504	switch (OID) {
505	case OID_GEN_CURRENT_PACKET_FILTER:
506
507		/* these NDIS_PACKET_TYPE_* bitflags are shared with
508		 * cdc_filter; it's not RNDIS-specific
509		 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
510		 *	PROMISCUOUS, DIRECTED,
511		 *	MULTICAST, ALL_MULTICAST, BROADCAST
512		 */
513		*params->filter = (u16)get_unaligned_le32(buf);
514		pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
515			__func__, *params->filter);
516
517		/* this call has a significant side effect:  it's
518		 * what makes the packet flow start and stop, like
519		 * activating the CDC Ethernet altsetting.
520		 */
521		retval = 0;
522		if (*params->filter) {
523			params->state = RNDIS_DATA_INITIALIZED;
524			netif_carrier_on(params->dev);
525			if (netif_running(params->dev))
526				netif_wake_queue (params->dev);
527		} else {
528			params->state = RNDIS_INITIALIZED;
529			netif_carrier_off (params->dev);
530			netif_stop_queue (params->dev);
531		}
532		break;
533
534	case OID_802_3_MULTICAST_LIST:
535		/* I think we can ignore this */
536		pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
537		retval = 0;
538		break;
539
540	default:
541		pr_warning("%s: set unknown OID 0x%08X, size %d\n",
542			 __func__, OID, buf_len);
543	}
544
545	return retval;
546}
547
548/*
549 * Response Functions
550 */
551
552static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
553{
554	rndis_init_cmplt_type	*resp;
555	rndis_resp_t            *r;
556	struct rndis_params	*params = rndis_per_dev_params + configNr;
557
558	if (!params->dev)
559		return -ENOTSUPP;
560
561	r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
562	if (!r)
563		return -ENOMEM;
564	resp = (rndis_init_cmplt_type *) r->buf;
565
566	resp->MessageType = cpu_to_le32 (
567			REMOTE_NDIS_INITIALIZE_CMPLT);
568	resp->MessageLength = cpu_to_le32 (52);
569	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
570	resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
571	resp->MajorVersion = cpu_to_le32 (RNDIS_MAJOR_VERSION);
572	resp->MinorVersion = cpu_to_le32 (RNDIS_MINOR_VERSION);
573	resp->DeviceFlags = cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);
574	resp->Medium = cpu_to_le32 (RNDIS_MEDIUM_802_3);
575	resp->MaxPacketsPerTransfer = cpu_to_le32 (1);
576	resp->MaxTransferSize = cpu_to_le32 (
577		  params->dev->mtu
578		+ sizeof (struct ethhdr)
579		+ sizeof (struct rndis_packet_msg_type)
580		+ 22);
581	resp->PacketAlignmentFactor = cpu_to_le32 (0);
582	resp->AFListOffset = cpu_to_le32 (0);
583	resp->AFListSize = cpu_to_le32 (0);
584
585	params->resp_avail(params->v);
586	return 0;
587}
588
589static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
590{
591	rndis_query_cmplt_type *resp;
592	rndis_resp_t            *r;
593	struct rndis_params	*params = rndis_per_dev_params + configNr;
594
595	/* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */
596	if (!params->dev)
597		return -ENOTSUPP;
598
599	/*
600	 * we need more memory:
601	 * gen_ndis_query_resp expects enough space for
602	 * rndis_query_cmplt_type followed by data.
603	 * oid_supported_list is the largest data reply
604	 */
605	r = rndis_add_response (configNr,
606		sizeof (oid_supported_list) + sizeof(rndis_query_cmplt_type));
607	if (!r)
608		return -ENOMEM;
609	resp = (rndis_query_cmplt_type *) r->buf;
610
611	resp->MessageType = cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
612	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
613
614	if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID),
615			le32_to_cpu(buf->InformationBufferOffset)
616					+ 8 + (u8 *) buf,
617			le32_to_cpu(buf->InformationBufferLength),
618			r)) {
619		/* OID not supported */
620		resp->Status = cpu_to_le32 (
621				RNDIS_STATUS_NOT_SUPPORTED);
622		resp->MessageLength = cpu_to_le32 (sizeof *resp);
623		resp->InformationBufferLength = cpu_to_le32 (0);
624		resp->InformationBufferOffset = cpu_to_le32 (0);
625	} else
626		resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
627
628	params->resp_avail(params->v);
629	return 0;
630}
631
632static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
633{
634	u32			BufLength, BufOffset;
635	rndis_set_cmplt_type	*resp;
636	rndis_resp_t		*r;
637	struct rndis_params	*params = rndis_per_dev_params + configNr;
638
639	r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
640	if (!r)
641		return -ENOMEM;
642	resp = (rndis_set_cmplt_type *) r->buf;
643
644	BufLength = le32_to_cpu (buf->InformationBufferLength);
645	BufOffset = le32_to_cpu (buf->InformationBufferOffset);
646
647#ifdef	VERBOSE_DEBUG
648	pr_debug("%s: Length: %d\n", __func__, BufLength);
649	pr_debug("%s: Offset: %d\n", __func__, BufOffset);
650	pr_debug("%s: InfoBuffer: ", __func__);
651
652	for (i = 0; i < BufLength; i++) {
653		pr_debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
654	}
655
656	pr_debug("\n");
657#endif
658
659	resp->MessageType = cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
660	resp->MessageLength = cpu_to_le32 (16);
661	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
662	if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID),
663			((u8 *) buf) + 8 + BufOffset, BufLength, r))
664		resp->Status = cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
665	else
666		resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
667
668	params->resp_avail(params->v);
669	return 0;
670}
671
672static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
673{
674	rndis_reset_cmplt_type	*resp;
675	rndis_resp_t		*r;
676	struct rndis_params	*params = rndis_per_dev_params + configNr;
677
678	r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
679	if (!r)
680		return -ENOMEM;
681	resp = (rndis_reset_cmplt_type *) r->buf;
682
683	resp->MessageType = cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
684	resp->MessageLength = cpu_to_le32 (16);
685	resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
686	/* resent information */
687	resp->AddressingReset = cpu_to_le32 (1);
688
689	params->resp_avail(params->v);
690	return 0;
691}
692
693static int rndis_keepalive_response (int configNr,
694				rndis_keepalive_msg_type *buf)
695{
696	rndis_keepalive_cmplt_type	*resp;
697	rndis_resp_t			*r;
698	struct rndis_params	*params = rndis_per_dev_params + configNr;
699
700	/* host "should" check only in RNDIS_DATA_INITIALIZED state */
701
702	r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
703	if (!r)
704		return -ENOMEM;
705	resp = (rndis_keepalive_cmplt_type *) r->buf;
706
707	resp->MessageType = cpu_to_le32 (
708			REMOTE_NDIS_KEEPALIVE_CMPLT);
709	resp->MessageLength = cpu_to_le32 (16);
710	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
711	resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS);
712
713	params->resp_avail(params->v);
714	return 0;
715}
716
717
718/*
719 * Device to Host Comunication
720 */
721static int rndis_indicate_status_msg (int configNr, u32 status)
722{
723	rndis_indicate_status_msg_type	*resp;
724	rndis_resp_t			*r;
725	struct rndis_params	*params = rndis_per_dev_params + configNr;
726
727	if (params->state == RNDIS_UNINITIALIZED)
728		return -ENOTSUPP;
729
730	r = rndis_add_response (configNr,
731				sizeof (rndis_indicate_status_msg_type));
732	if (!r)
733		return -ENOMEM;
734	resp = (rndis_indicate_status_msg_type *) r->buf;
735
736	resp->MessageType = cpu_to_le32 (
737			REMOTE_NDIS_INDICATE_STATUS_MSG);
738	resp->MessageLength = cpu_to_le32 (20);
739	resp->Status = cpu_to_le32 (status);
740	resp->StatusBufferLength = cpu_to_le32 (0);
741	resp->StatusBufferOffset = cpu_to_le32 (0);
742
743	params->resp_avail(params->v);
744	return 0;
745}
746
747int rndis_signal_connect (int configNr)
748{
749	rndis_per_dev_params [configNr].media_state
750			= NDIS_MEDIA_STATE_CONNECTED;
751	return rndis_indicate_status_msg (configNr,
752					  RNDIS_STATUS_MEDIA_CONNECT);
753}
754
755int rndis_signal_disconnect (int configNr)
756{
757	rndis_per_dev_params [configNr].media_state
758			= NDIS_MEDIA_STATE_DISCONNECTED;
759	return rndis_indicate_status_msg (configNr,
760					  RNDIS_STATUS_MEDIA_DISCONNECT);
761}
762
763void rndis_uninit (int configNr)
764{
765	u8 *buf;
766	u32 length;
767
768	if (configNr >= RNDIS_MAX_CONFIGS)
769		return;
770	rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;
771
772	/* drain the response queue */
773	while ((buf = rndis_get_next_response(configNr, &length)))
774		rndis_free_response(configNr, buf);
775}
776
777void rndis_set_host_mac (int configNr, const u8 *addr)
778{
779	rndis_per_dev_params [configNr].host_mac = addr;
780}
781
782/*
783 * Message Parser
784 */
785int rndis_msg_parser (u8 configNr, u8 *buf)
786{
787	u32 MsgType, MsgLength;
788	__le32 *tmp;
789	struct rndis_params		*params;
790
791	if (!buf)
792		return -ENOMEM;
793
794	tmp = (__le32 *) buf;
795	MsgType   = get_unaligned_le32(tmp++);
796	MsgLength = get_unaligned_le32(tmp++);
797
798	if (configNr >= RNDIS_MAX_CONFIGS)
799		return -ENOTSUPP;
800	params = &rndis_per_dev_params [configNr];
801
802	/* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
803	 * rx/tx statistics and link status, in addition to KEEPALIVE traffic
804	 * and normal HC level polling to see if there's any IN traffic.
805	 */
806
807	/* For USB: responses may take up to 10 seconds */
808	switch (MsgType) {
809	case REMOTE_NDIS_INITIALIZE_MSG:
810		pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
811			__func__ );
812		params->state = RNDIS_INITIALIZED;
813		return  rndis_init_response (configNr,
814					(rndis_init_msg_type *) buf);
815
816	case REMOTE_NDIS_HALT_MSG:
817		pr_debug("%s: REMOTE_NDIS_HALT_MSG\n",
818			__func__ );
819		params->state = RNDIS_UNINITIALIZED;
820		if (params->dev) {
821			netif_carrier_off (params->dev);
822			netif_stop_queue (params->dev);
823		}
824		return 0;
825
826	case REMOTE_NDIS_QUERY_MSG:
827		return rndis_query_response (configNr,
828					(rndis_query_msg_type *) buf);
829
830	case REMOTE_NDIS_SET_MSG:
831		return rndis_set_response (configNr,
832					(rndis_set_msg_type *) buf);
833
834	case REMOTE_NDIS_RESET_MSG:
835		pr_debug("%s: REMOTE_NDIS_RESET_MSG\n",
836			__func__ );
837		return rndis_reset_response (configNr,
838					(rndis_reset_msg_type *) buf);
839
840	case REMOTE_NDIS_KEEPALIVE_MSG:
841		/* For USB: host does this every 5 seconds */
842		if (rndis_debug > 1)
843			pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
844				__func__ );
845		return rndis_keepalive_response (configNr,
846						 (rndis_keepalive_msg_type *)
847						 buf);
848
849	default:
850		/* At least Windows XP emits some undefined RNDIS messages.
851		 * In one case those messages seemed to relate to the host
852		 * suspending itself.
853		 */
854		pr_warning("%s: unknown RNDIS message 0x%08X len %d\n",
855			__func__ , MsgType, MsgLength);
856		{
857			unsigned i;
858			for (i = 0; i < MsgLength; i += 16) {
859				pr_debug("%03d: "
860					" %02x %02x %02x %02x"
861					" %02x %02x %02x %02x"
862					" %02x %02x %02x %02x"
863					" %02x %02x %02x %02x"
864					"\n",
865					i,
866					buf[i], buf [i+1],
867						buf[i+2], buf[i+3],
868					buf[i+4], buf [i+5],
869						buf[i+6], buf[i+7],
870					buf[i+8], buf [i+9],
871						buf[i+10], buf[i+11],
872					buf[i+12], buf [i+13],
873						buf[i+14], buf[i+15]);
874			}
875		}
876		break;
877	}
878
879	return -ENOTSUPP;
880}
881
882int rndis_register(void (*resp_avail)(void *v), void *v)
883{
884	u8 i;
885
886	if (!resp_avail)
887		return -EINVAL;
888
889	for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
890		if (!rndis_per_dev_params [i].used) {
891			rndis_per_dev_params [i].used = 1;
892			rndis_per_dev_params [i].resp_avail = resp_avail;
893			rndis_per_dev_params [i].v = v;
894			pr_debug("%s: configNr = %d\n", __func__, i);
895			return i;
896		}
897	}
898	pr_debug("failed\n");
899
900	return -ENODEV;
901}
902
903void rndis_deregister (int configNr)
904{
905	pr_debug("%s: \n", __func__);
906
907	if (configNr >= RNDIS_MAX_CONFIGS) return;
908	rndis_per_dev_params [configNr].used = 0;
909
910	return;
911}
912
913int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
914{
915	pr_debug("%s:\n", __func__);
916	if (!dev)
917		return -EINVAL;
918	if (configNr >= RNDIS_MAX_CONFIGS) return -1;
919
920	rndis_per_dev_params [configNr].dev = dev;
921	rndis_per_dev_params [configNr].filter = cdc_filter;
922
923	return 0;
924}
925
926int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
927{
928	pr_debug("%s:\n", __func__);
929	if (!vendorDescr) return -1;
930	if (configNr >= RNDIS_MAX_CONFIGS) return -1;
931
932	rndis_per_dev_params [configNr].vendorID = vendorID;
933	rndis_per_dev_params [configNr].vendorDescr = vendorDescr;
934
935	return 0;
936}
937
938int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
939{
940	pr_debug("%s: %u %u\n", __func__, medium, speed);
941	if (configNr >= RNDIS_MAX_CONFIGS) return -1;
942
943	rndis_per_dev_params [configNr].medium = medium;
944	rndis_per_dev_params [configNr].speed = speed;
945
946	return 0;
947}
948
949void rndis_add_hdr (struct sk_buff *skb)
950{
951	struct rndis_packet_msg_type	*header;
952
953	if (!skb)
954		return;
955	header = (void *) skb_push (skb, sizeof *header);
956	memset (header, 0, sizeof *header);
957	header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
958	header->MessageLength = cpu_to_le32(skb->len);
959	header->DataOffset = cpu_to_le32 (36);
960	header->DataLength = cpu_to_le32(skb->len - sizeof *header);
961}
962
963void rndis_free_response (int configNr, u8 *buf)
964{
965	rndis_resp_t		*r;
966	struct list_head	*act, *tmp;
967
968	list_for_each_safe (act, tmp,
969			&(rndis_per_dev_params [configNr].resp_queue))
970	{
971		r = list_entry (act, rndis_resp_t, list);
972		if (r && r->buf == buf) {
973			list_del (&r->list);
974			kfree (r);
975		}
976	}
977}
978
979u8 *rndis_get_next_response (int configNr, u32 *length)
980{
981	rndis_resp_t		*r;
982	struct list_head	*act, *tmp;
983
984	if (!length) return NULL;
985
986	list_for_each_safe (act, tmp,
987			&(rndis_per_dev_params [configNr].resp_queue))
988	{
989		r = list_entry (act, rndis_resp_t, list);
990		if (!r->send) {
991			r->send = 1;
992			*length = r->length;
993			return r->buf;
994		}
995	}
996
997	return NULL;
998}
999
1000static rndis_resp_t *rndis_add_response (int configNr, u32 length)
1001{
1002	rndis_resp_t	*r;
1003
1004	/* NOTE:  this gets copied into ether.c USB_BUFSIZ bytes ... */
1005	r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);
1006	if (!r) return NULL;
1007
1008	r->buf = (u8 *) (r + 1);
1009	r->length = length;
1010	r->send = 0;
1011
1012	list_add_tail (&r->list,
1013		&(rndis_per_dev_params [configNr].resp_queue));
1014	return r;
1015}
1016
1017int rndis_rm_hdr(struct gether *port,
1018			struct sk_buff *skb,
1019			struct sk_buff_head *list)
1020{
1021	/* tmp points to a struct rndis_packet_msg_type */
1022	__le32		*tmp = (void *) skb->data;
1023
1024	/* MessageType, MessageLength */
1025	if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG)
1026			!= get_unaligned(tmp++)) {
1027		dev_kfree_skb_any(skb);
1028		return -EINVAL;
1029	}
1030	tmp++;
1031
1032	/* DataOffset, DataLength */
1033	if (!skb_pull(skb, get_unaligned_le32(tmp++) + 8)) {
1034		dev_kfree_skb_any(skb);
1035		return -EOVERFLOW;
1036	}
1037	skb_trim(skb, get_unaligned_le32(tmp++));
1038
1039	skb_queue_tail(list, skb);
1040	return 0;
1041}
1042
1043#ifdef	CONFIG_USB_GADGET_DEBUG_FILES
1044
1045static int rndis_proc_show(struct seq_file *m, void *v)
1046{
1047	rndis_params *param = m->private;
1048
1049	seq_printf(m,
1050			 "Config Nr. %d\n"
1051			 "used      : %s\n"
1052			 "state     : %s\n"
1053			 "medium    : 0x%08X\n"
1054			 "speed     : %d\n"
1055			 "cable     : %s\n"
1056			 "vendor ID : 0x%08X\n"
1057			 "vendor    : %s\n",
1058			 param->confignr, (param->used) ? "y" : "n",
1059			 ({ char *s = "?";
1060			 switch (param->state) {
1061			 case RNDIS_UNINITIALIZED:
1062				s = "RNDIS_UNINITIALIZED"; break;
1063			 case RNDIS_INITIALIZED:
1064				s = "RNDIS_INITIALIZED"; break;
1065			 case RNDIS_DATA_INITIALIZED:
1066				s = "RNDIS_DATA_INITIALIZED"; break;
1067			}; s; }),
1068			 param->medium,
1069			 (param->media_state) ? 0 : param->speed*100,
1070			 (param->media_state) ? "disconnected" : "connected",
1071			 param->vendorID, param->vendorDescr);
1072	return 0;
1073}
1074
1075static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
1076		size_t count, loff_t *ppos)
1077{
1078	rndis_params *p = PDE(file->f_path.dentry->d_inode)->data;
1079	u32 speed = 0;
1080	int i, fl_speed = 0;
1081
1082	for (i = 0; i < count; i++) {
1083		char c;
1084		if (get_user(c, buffer))
1085			return -EFAULT;
1086		switch (c) {
1087		case '0':
1088		case '1':
1089		case '2':
1090		case '3':
1091		case '4':
1092		case '5':
1093		case '6':
1094		case '7':
1095		case '8':
1096		case '9':
1097			fl_speed = 1;
1098			speed = speed*10 + c - '0';
1099			break;
1100		case 'C':
1101		case 'c':
1102			rndis_signal_connect (p->confignr);
1103			break;
1104		case 'D':
1105		case 'd':
1106			rndis_signal_disconnect(p->confignr);
1107			break;
1108		default:
1109			if (fl_speed) p->speed = speed;
1110			else pr_debug("%c is not valid\n", c);
1111			break;
1112		}
1113
1114		buffer++;
1115	}
1116
1117	return count;
1118}
1119
1120static int rndis_proc_open(struct inode *inode, struct file *file)
1121{
1122	return single_open(file, rndis_proc_show, PDE(inode)->data);
1123}
1124
1125static const struct file_operations rndis_proc_fops = {
1126	.owner		= THIS_MODULE,
1127	.open		= rndis_proc_open,
1128	.read		= seq_read,
1129	.llseek		= seq_lseek,
1130	.release	= single_release,
1131	.write		= rndis_proc_write,
1132};
1133
1134#define	NAME_TEMPLATE	"driver/rndis-%03d"
1135
1136static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
1137
1138#endif	/* CONFIG_USB_GADGET_DEBUG_FILES */
1139
1140
1141int rndis_init(void)
1142{
1143	u8 i;
1144
1145	for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1146#ifdef	CONFIG_USB_GADGET_DEBUG_FILES
1147		char name [20];
1148
1149		sprintf (name, NAME_TEMPLATE, i);
1150		if (!(rndis_connect_state [i]
1151				= proc_create_data(name, 0660, NULL,
1152					&rndis_proc_fops,
1153					(void *)(rndis_per_dev_params + i))))
1154		{
1155			pr_debug("%s :remove entries", __func__);
1156			while (i) {
1157				sprintf (name, NAME_TEMPLATE, --i);
1158				remove_proc_entry (name, NULL);
1159			}
1160			pr_debug("\n");
1161			return -EIO;
1162		}
1163#endif
1164		rndis_per_dev_params [i].confignr = i;
1165		rndis_per_dev_params [i].used = 0;
1166		rndis_per_dev_params [i].state = RNDIS_UNINITIALIZED;
1167		rndis_per_dev_params [i].media_state
1168				= NDIS_MEDIA_STATE_DISCONNECTED;
1169		INIT_LIST_HEAD (&(rndis_per_dev_params [i].resp_queue));
1170	}
1171
1172	return 0;
1173}
1174
1175void rndis_exit (void)
1176{
1177#ifdef	CONFIG_USB_GADGET_DEBUG_FILES
1178	u8 i;
1179	char name [20];
1180
1181	for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1182		sprintf (name, NAME_TEMPLATE, i);
1183		remove_proc_entry (name, NULL);
1184	}
1185#endif
1186}
1187