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