aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/ether.c24
-rw-r--r--drivers/usb/gadget/ndis.h10
-rw-r--r--drivers/usb/gadget/rndis.c366
-rw-r--r--drivers/usb/gadget/rndis.h7
4 files changed, 79 insertions, 328 deletions
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index d3891b2fc36e..dee1f081165d 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -1106,6 +1106,8 @@ static void eth_reset_config (struct eth_dev *dev)
1106 1106
1107 netif_stop_queue (dev->net); 1107 netif_stop_queue (dev->net);
1108 netif_carrier_off (dev->net); 1108 netif_carrier_off (dev->net);
1109
1110 /* RNDIS enters RNDIS_UNINITIALIZED state */
1109 rndis_uninit(dev->rndis_config); 1111 rndis_uninit(dev->rndis_config);
1110 1112
1111 /* disable endpoints, forcing (synchronous) completion of 1113 /* disable endpoints, forcing (synchronous) completion of
@@ -1604,8 +1606,6 @@ eth_disconnect (struct usb_gadget *gadget)
1604 eth_reset_config (dev); 1606 eth_reset_config (dev);
1605 spin_unlock_irqrestore (&dev->lock, flags); 1607 spin_unlock_irqrestore (&dev->lock, flags);
1606 1608
1607 /* FIXME RNDIS should enter RNDIS_UNINITIALIZED */
1608
1609 /* next we may get setup() calls to enumerate new connections; 1609 /* next we may get setup() calls to enumerate new connections;
1610 * or an unbind() during shutdown (including removing module). 1610 * or an unbind() during shutdown (including removing module).
1611 */ 1611 */
@@ -2067,23 +2067,23 @@ rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
2067 eth_req_free(ep, req); 2067 eth_req_free(ep, req);
2068} 2068}
2069 2069
2070static int rndis_control_ack (struct net_device *net) 2070static void rndis_resp_avail(void *_dev)
2071{ 2071{
2072 struct eth_dev *dev = netdev_priv(net); 2072 struct eth_dev *dev = _dev;
2073 int length; 2073 int length;
2074 struct usb_request *resp = dev->stat_req; 2074 struct usb_request *resp = dev->stat_req;
2075 2075
2076 /* in case RNDIS calls this after disconnect */ 2076 /* in case RNDIS calls this after disconnect */
2077 if (!dev->status) { 2077 if (!dev->status) {
2078 DEBUG (dev, "status ENODEV\n"); 2078 DEBUG (dev, "status ENODEV\n");
2079 return -ENODEV; 2079 return;
2080 } 2080 }
2081 2081
2082 /* in case queue length > 1 */ 2082 /* in case queue length > 1 */
2083 if (resp->context) { 2083 if (resp->context) {
2084 resp = eth_req_alloc (dev->status_ep, 8, GFP_ATOMIC); 2084 resp = eth_req_alloc (dev->status_ep, 8, GFP_ATOMIC);
2085 if (!resp) 2085 if (!resp)
2086 return -ENOMEM; 2086 return;
2087 } 2087 }
2088 2088
2089 /* Send RNDIS RESPONSE_AVAILABLE notification; 2089 /* Send RNDIS RESPONSE_AVAILABLE notification;
@@ -2101,13 +2101,11 @@ static int rndis_control_ack (struct net_device *net)
2101 resp->status = 0; 2101 resp->status = 0;
2102 rndis_control_ack_complete (dev->status_ep, resp); 2102 rndis_control_ack_complete (dev->status_ep, resp);
2103 } 2103 }
2104
2105 return 0;
2106} 2104}
2107 2105
2108#else 2106#else
2109 2107
2110#define rndis_control_ack NULL 2108#define rndis_resp_avail NULL
2111 2109
2112#endif /* RNDIS */ 2110#endif /* RNDIS */
2113 2111
@@ -2566,18 +2564,18 @@ autoconf_fail:
2566 2564
2567 /* FIXME RNDIS vendor id == "vendor NIC code" == ? */ 2565 /* FIXME RNDIS vendor id == "vendor NIC code" == ? */
2568 2566
2569 dev->rndis_config = rndis_register (rndis_control_ack); 2567 status = rndis_register(rndis_resp_avail, dev);
2570 if (dev->rndis_config < 0) { 2568 if (status < 0) {
2571fail0: 2569fail0:
2572 unregister_netdev (dev->net); 2570 unregister_netdev (dev->net);
2573 status = -ENODEV;
2574 goto fail; 2571 goto fail;
2575 } 2572 }
2573 dev->rndis_config = status;
2576 2574
2577 /* these set up a lot of the OIDs that RNDIS needs */ 2575 /* these set up a lot of the OIDs that RNDIS needs */
2578 rndis_set_host_mac (dev->rndis_config, dev->host_mac); 2576 rndis_set_host_mac (dev->rndis_config, dev->host_mac);
2579 if (rndis_set_param_dev (dev->rndis_config, dev->net, 2577 if (rndis_set_param_dev (dev->rndis_config, dev->net,
2580 &dev->stats, &dev->cdc_filter)) 2578 &dev->cdc_filter))
2581 goto fail0; 2579 goto fail0;
2582 if (rndis_set_param_vendor(dev->rndis_config, vendorID, 2580 if (rndis_set_param_vendor(dev->rndis_config, vendorID,
2583 manufacturer)) 2581 manufacturer))
diff --git a/drivers/usb/gadget/ndis.h b/drivers/usb/gadget/ndis.h
index 09e3ee4eeae1..df886cec5ef4 100644
--- a/drivers/usb/gadget/ndis.h
+++ b/drivers/usb/gadget/ndis.h
@@ -1,11 +1,11 @@
1/* 1/*
2 * ndis.h 2 * ndis.h
3 * 3 *
4 * ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de> 4 * ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de>
5 * 5 *
6 * Thanks to the cygwin development team, 6 * Thanks to the cygwin development team,
7 * espacially to Casper S. Hornstrup <chorns@users.sourceforge.net> 7 * espacially to Casper S. Hornstrup <chorns@users.sourceforge.net>
8 * 8 *
9 * THIS SOFTWARE IS NOT COPYRIGHTED 9 * THIS SOFTWARE IS NOT COPYRIGHTED
10 * 10 *
11 * This source code is offered for use in the public domain. You may 11 * This source code is offered for use in the public domain. You may
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index d252015576fb..7228e8562236 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -37,9 +37,7 @@
37#include <asm/unaligned.h> 37#include <asm/unaligned.h>
38 38
39 39
40#undef RNDIS_PM 40#undef VERBOSE_DEBUG
41#undef RNDIS_WAKEUP
42#undef VERBOSE
43 41
44#include "rndis.h" 42#include "rndis.h"
45 43
@@ -95,9 +93,6 @@ static const u32 oid_supported_list [] =
95 OID_GEN_MAXIMUM_TOTAL_SIZE, 93 OID_GEN_MAXIMUM_TOTAL_SIZE,
96 OID_GEN_MEDIA_CONNECT_STATUS, 94 OID_GEN_MEDIA_CONNECT_STATUS,
97 OID_GEN_PHYSICAL_MEDIUM, 95 OID_GEN_PHYSICAL_MEDIUM,
98#if 0
99 OID_GEN_RNDIS_CONFIG_PARAMETER,
100#endif
101 96
102 /* the statistical stuff */ 97 /* the statistical stuff */
103 OID_GEN_XMIT_OK, 98 OID_GEN_XMIT_OK,
@@ -145,7 +140,14 @@ static const u32 oid_supported_list [] =
145#endif /* RNDIS_OPTIONAL_STATS */ 140#endif /* RNDIS_OPTIONAL_STATS */
146 141
147#ifdef RNDIS_PM 142#ifdef RNDIS_PM
148 /* PM and wakeup are mandatory for USB: */ 143 /* PM and wakeup are "mandatory" for USB, but the RNDIS specs
144 * don't say what they mean ... and the NDIS specs are often
145 * confusing and/or ambiguous in this context. (That is, more
146 * so than their specs for the other OIDs.)
147 *
148 * FIXME someone who knows what these should do, please
149 * implement them!
150 */
149 151
150 /* power management */ 152 /* power management */
151 OID_PNP_CAPABILITIES, 153 OID_PNP_CAPABILITIES,
@@ -172,6 +174,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
172 __le32 *outbuf; 174 __le32 *outbuf;
173 int i, count; 175 int i, count;
174 rndis_query_cmplt_type *resp; 176 rndis_query_cmplt_type *resp;
177 struct net_device *net;
178 struct net_device_stats *stats;
175 179
176 if (!r) return -ENOMEM; 180 if (!r) return -ENOMEM;
177 resp = (rndis_query_cmplt_type *) r->buf; 181 resp = (rndis_query_cmplt_type *) r->buf;
@@ -193,6 +197,12 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
193 outbuf = (__le32 *) &resp[1]; 197 outbuf = (__le32 *) &resp[1];
194 resp->InformationBufferOffset = __constant_cpu_to_le32 (16); 198 resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
195 199
200 net = rndis_per_dev_params[configNr].dev;
201 if (net->get_stats)
202 stats = net->get_stats(net);
203 else
204 stats = NULL;
205
196 switch (OID) { 206 switch (OID) {
197 207
198 /* general oids (table 4-1) */ 208 /* general oids (table 4-1) */
@@ -349,11 +359,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
349 case OID_GEN_XMIT_OK: 359 case OID_GEN_XMIT_OK:
350 if (rndis_debug > 1) 360 if (rndis_debug > 1)
351 DBG("%s: OID_GEN_XMIT_OK\n", __func__); 361 DBG("%s: OID_GEN_XMIT_OK\n", __func__);
352 if (rndis_per_dev_params [configNr].stats) { 362 if (stats) {
353 *outbuf = cpu_to_le32 ( 363 *outbuf = cpu_to_le32(stats->tx_packets
354 rndis_per_dev_params [configNr].stats->tx_packets - 364 - stats->tx_errors - stats->tx_dropped);
355 rndis_per_dev_params [configNr].stats->tx_errors -
356 rndis_per_dev_params [configNr].stats->tx_dropped);
357 retval = 0; 365 retval = 0;
358 } 366 }
359 break; 367 break;
@@ -362,11 +370,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
362 case OID_GEN_RCV_OK: 370 case OID_GEN_RCV_OK:
363 if (rndis_debug > 1) 371 if (rndis_debug > 1)
364 DBG("%s: OID_GEN_RCV_OK\n", __func__); 372 DBG("%s: OID_GEN_RCV_OK\n", __func__);
365 if (rndis_per_dev_params [configNr].stats) { 373 if (stats) {
366 *outbuf = cpu_to_le32 ( 374 *outbuf = cpu_to_le32(stats->rx_packets
367 rndis_per_dev_params [configNr].stats->rx_packets - 375 - stats->rx_errors - stats->rx_dropped);
368 rndis_per_dev_params [configNr].stats->rx_errors -
369 rndis_per_dev_params [configNr].stats->rx_dropped);
370 retval = 0; 376 retval = 0;
371 } 377 }
372 break; 378 break;
@@ -375,9 +381,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
375 case OID_GEN_XMIT_ERROR: 381 case OID_GEN_XMIT_ERROR:
376 if (rndis_debug > 1) 382 if (rndis_debug > 1)
377 DBG("%s: OID_GEN_XMIT_ERROR\n", __func__); 383 DBG("%s: OID_GEN_XMIT_ERROR\n", __func__);
378 if (rndis_per_dev_params [configNr].stats) { 384 if (stats) {
379 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] 385 *outbuf = cpu_to_le32(stats->tx_errors);
380 .stats->tx_errors);
381 retval = 0; 386 retval = 0;
382 } 387 }
383 break; 388 break;
@@ -386,9 +391,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
386 case OID_GEN_RCV_ERROR: 391 case OID_GEN_RCV_ERROR:
387 if (rndis_debug > 1) 392 if (rndis_debug > 1)
388 DBG("%s: OID_GEN_RCV_ERROR\n", __func__); 393 DBG("%s: OID_GEN_RCV_ERROR\n", __func__);
389 if (rndis_per_dev_params [configNr].stats) { 394 if (stats) {
390 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] 395 *outbuf = cpu_to_le32(stats->rx_errors);
391 .stats->rx_errors);
392 retval = 0; 396 retval = 0;
393 } 397 }
394 break; 398 break;
@@ -396,150 +400,12 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
396 /* mandatory */ 400 /* mandatory */
397 case OID_GEN_RCV_NO_BUFFER: 401 case OID_GEN_RCV_NO_BUFFER:
398 DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__); 402 DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
399 if (rndis_per_dev_params [configNr].stats) { 403 if (stats) {
400 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] 404 *outbuf = cpu_to_le32(stats->rx_dropped);
401 .stats->rx_dropped);
402 retval = 0;
403 }
404 break;
405
406#ifdef RNDIS_OPTIONAL_STATS
407 case OID_GEN_DIRECTED_BYTES_XMIT:
408 DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __func__);
409 /*
410 * Aunt Tilly's size of shoes
411 * minus antarctica count of penguins
412 * divided by weight of Alpha Centauri
413 */
414 if (rndis_per_dev_params [configNr].stats) {
415 *outbuf = cpu_to_le32 (
416 (rndis_per_dev_params [configNr]
417 .stats->tx_packets -
418 rndis_per_dev_params [configNr]
419 .stats->tx_errors -
420 rndis_per_dev_params [configNr]
421 .stats->tx_dropped)
422 * 123);
423 retval = 0;
424 }
425 break;
426
427 case OID_GEN_DIRECTED_FRAMES_XMIT:
428 DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __func__);
429 /* dito */
430 if (rndis_per_dev_params [configNr].stats) {
431 *outbuf = cpu_to_le32 (
432 (rndis_per_dev_params [configNr]
433 .stats->tx_packets -
434 rndis_per_dev_params [configNr]
435 .stats->tx_errors -
436 rndis_per_dev_params [configNr]
437 .stats->tx_dropped)
438 / 123);
439 retval = 0;
440 }
441 break;
442
443 case OID_GEN_MULTICAST_BYTES_XMIT:
444 DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __func__);
445 if (rndis_per_dev_params [configNr].stats) {
446 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
447 .stats->multicast*1234);
448 retval = 0;
449 }
450 break;
451
452 case OID_GEN_MULTICAST_FRAMES_XMIT:
453 DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __func__);
454 if (rndis_per_dev_params [configNr].stats) {
455 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
456 .stats->multicast);
457 retval = 0;
458 }
459 break;
460
461 case OID_GEN_BROADCAST_BYTES_XMIT:
462 DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __func__);
463 if (rndis_per_dev_params [configNr].stats) {
464 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
465 .stats->tx_packets/42*255);
466 retval = 0;
467 }
468 break;
469
470 case OID_GEN_BROADCAST_FRAMES_XMIT:
471 DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __func__);
472 if (rndis_per_dev_params [configNr].stats) {
473 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
474 .stats->tx_packets/42);
475 retval = 0;
476 }
477 break;
478
479 case OID_GEN_DIRECTED_BYTES_RCV:
480 DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __func__);
481 *outbuf = __constant_cpu_to_le32 (0);
482 retval = 0;
483 break;
484
485 case OID_GEN_DIRECTED_FRAMES_RCV:
486 DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __func__);
487 *outbuf = __constant_cpu_to_le32 (0);
488 retval = 0;
489 break;
490
491 case OID_GEN_MULTICAST_BYTES_RCV:
492 DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __func__);
493 if (rndis_per_dev_params [configNr].stats) {
494 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
495 .stats->multicast * 1111);
496 retval = 0;
497 }
498 break;
499
500 case OID_GEN_MULTICAST_FRAMES_RCV:
501 DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __func__);
502 if (rndis_per_dev_params [configNr].stats) {
503 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
504 .stats->multicast);
505 retval = 0;
506 }
507 break;
508
509 case OID_GEN_BROADCAST_BYTES_RCV:
510 DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __func__);
511 if (rndis_per_dev_params [configNr].stats) {
512 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
513 .stats->rx_packets/42*255);
514 retval = 0;
515 }
516 break;
517
518 case OID_GEN_BROADCAST_FRAMES_RCV:
519 DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __func__);
520 if (rndis_per_dev_params [configNr].stats) {
521 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
522 .stats->rx_packets/42);
523 retval = 0;
524 }
525 break;
526
527 case OID_GEN_RCV_CRC_ERROR:
528 DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __func__);
529 if (rndis_per_dev_params [configNr].stats) {
530 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
531 .stats->rx_crc_errors);
532 retval = 0; 405 retval = 0;
533 } 406 }
534 break; 407 break;
535 408
536 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
537 DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __func__);
538 *outbuf = __constant_cpu_to_le32 (0);
539 retval = 0;
540 break;
541#endif /* RNDIS_OPTIONAL_STATS */
542
543 /* ieee802.3 OIDs (table 4-3) */ 409 /* ieee802.3 OIDs (table 4-3) */
544 410
545 /* mandatory */ 411 /* mandatory */
@@ -591,9 +457,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
591 /* mandatory */ 457 /* mandatory */
592 case OID_802_3_RCV_ERROR_ALIGNMENT: 458 case OID_802_3_RCV_ERROR_ALIGNMENT:
593 DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__); 459 DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
594 if (rndis_per_dev_params [configNr].stats) { 460 if (stats) {
595 *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr] 461 *outbuf = cpu_to_le32(stats->rx_frame_errors);
596 .stats->rx_frame_errors);
597 retval = 0; 462 retval = 0;
598 } 463 }
599 break; 464 break;
@@ -612,64 +477,6 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
612 retval = 0; 477 retval = 0;
613 break; 478 break;
614 479
615#ifdef RNDIS_OPTIONAL_STATS
616 case OID_802_3_XMIT_DEFERRED:
617 DBG("%s: OID_802_3_XMIT_DEFERRED\n", __func__);
618 /* TODO */
619 break;
620
621 case OID_802_3_XMIT_MAX_COLLISIONS:
622 DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __func__);
623 /* TODO */
624 break;
625
626 case OID_802_3_RCV_OVERRUN:
627 DBG("%s: OID_802_3_RCV_OVERRUN\n", __func__);
628 /* TODO */
629 break;
630
631 case OID_802_3_XMIT_UNDERRUN:
632 DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __func__);
633 /* TODO */
634 break;
635
636 case OID_802_3_XMIT_HEARTBEAT_FAILURE:
637 DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __func__);
638 /* TODO */
639 break;
640
641 case OID_802_3_XMIT_TIMES_CRS_LOST:
642 DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __func__);
643 /* TODO */
644 break;
645
646 case OID_802_3_XMIT_LATE_COLLISIONS:
647 DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __func__);
648 /* TODO */
649 break;
650#endif /* RNDIS_OPTIONAL_STATS */
651
652#ifdef RNDIS_PM
653 /* power management OIDs (table 4-5) */
654 case OID_PNP_CAPABILITIES:
655 DBG("%s: OID_PNP_CAPABILITIES\n", __func__);
656
657 /* for now, no wakeup capabilities */
658 length = sizeof (struct NDIS_PNP_CAPABILITIES);
659 memset(outbuf, 0, length);
660 retval = 0;
661 break;
662 case OID_PNP_QUERY_POWER:
663 DBG("%s: OID_PNP_QUERY_POWER D%d\n", __func__,
664 get_unaligned_le32(buf) - 1);
665 /* only suspend is a real power state, and
666 * it can't be entered by OID_PNP_SET_POWER...
667 */
668 length = 0;
669 retval = 0;
670 break;
671#endif
672
673 default: 480 default:
674 pr_warning("%s: query unknown OID 0x%08X\n", 481 pr_warning("%s: query unknown OID 0x%08X\n",
675 __func__, OID); 482 __func__, OID);
@@ -725,9 +532,6 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
725 * what makes the packet flow start and stop, like 532 * what makes the packet flow start and stop, like
726 * activating the CDC Ethernet altsetting. 533 * activating the CDC Ethernet altsetting.
727 */ 534 */
728#ifdef RNDIS_PM
729update_linkstate:
730#endif
731 retval = 0; 535 retval = 0;
732 if (*params->filter) { 536 if (*params->filter) {
733 params->state = RNDIS_DATA_INITIALIZED; 537 params->state = RNDIS_DATA_INITIALIZED;
@@ -746,49 +550,6 @@ update_linkstate:
746 DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__); 550 DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
747 retval = 0; 551 retval = 0;
748 break; 552 break;
749#if 0
750 case OID_GEN_RNDIS_CONFIG_PARAMETER:
751 {
752 struct rndis_config_parameter *param;
753 param = (struct rndis_config_parameter *) buf;
754 DBG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
755 __func__,
756 min(cpu_to_le32(param->ParameterNameLength),80),
757 buf + param->ParameterNameOffset);
758 retval = 0;
759 }
760 break;
761#endif
762
763#ifdef RNDIS_PM
764 case OID_PNP_SET_POWER:
765 /* The only real power state is USB suspend, and RNDIS requests
766 * can't enter it; this one isn't really about power. After
767 * resuming, Windows forces a reset, and then SET_POWER D0.
768 * FIXME ... then things go batty; Windows wedges itself.
769 */
770 i = get_unaligned_le32(buf);
771 DBG("%s: OID_PNP_SET_POWER D%d\n", __func__, i - 1);
772 switch (i) {
773 case NdisDeviceStateD0:
774 *params->filter = params->saved_filter;
775 goto update_linkstate;
776 case NdisDeviceStateD3:
777 case NdisDeviceStateD2:
778 case NdisDeviceStateD1:
779 params->saved_filter = *params->filter;
780 retval = 0;
781 break;
782 }
783 break;
784
785#ifdef RNDIS_WAKEUP
786 // no wakeup support advertised, so wakeup OIDs always fail:
787 // - OID_PNP_ENABLE_WAKE_UP
788 // - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN
789#endif
790
791#endif /* RNDIS_PM */
792 553
793 default: 554 default:
794 pr_warning("%s: set unknown OID 0x%08X, size %d\n", 555 pr_warning("%s: set unknown OID 0x%08X, size %d\n",
@@ -806,8 +567,10 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
806{ 567{
807 rndis_init_cmplt_type *resp; 568 rndis_init_cmplt_type *resp;
808 rndis_resp_t *r; 569 rndis_resp_t *r;
570 struct rndis_params *params = rndis_per_dev_params + configNr;
809 571
810 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; 572 if (!params->dev)
573 return -ENOTSUPP;
811 574
812 r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type)); 575 r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
813 if (!r) 576 if (!r)
@@ -825,7 +588,7 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
825 resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3); 588 resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3);
826 resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1); 589 resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1);
827 resp->MaxTransferSize = cpu_to_le32 ( 590 resp->MaxTransferSize = cpu_to_le32 (
828 rndis_per_dev_params [configNr].dev->mtu 591 params->dev->mtu
829 + sizeof (struct ethhdr) 592 + sizeof (struct ethhdr)
830 + sizeof (struct rndis_packet_msg_type) 593 + sizeof (struct rndis_packet_msg_type)
831 + 22); 594 + 22);
@@ -833,10 +596,7 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
833 resp->AFListOffset = __constant_cpu_to_le32 (0); 596 resp->AFListOffset = __constant_cpu_to_le32 (0);
834 resp->AFListSize = __constant_cpu_to_le32 (0); 597 resp->AFListSize = __constant_cpu_to_le32 (0);
835 598
836 if (rndis_per_dev_params [configNr].ack) 599 params->resp_avail(params->v);
837 rndis_per_dev_params [configNr].ack (
838 rndis_per_dev_params [configNr].dev);
839
840 return 0; 600 return 0;
841} 601}
842 602
@@ -844,9 +604,11 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
844{ 604{
845 rndis_query_cmplt_type *resp; 605 rndis_query_cmplt_type *resp;
846 rndis_resp_t *r; 606 rndis_resp_t *r;
607 struct rndis_params *params = rndis_per_dev_params + configNr;
847 608
848 // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); 609 // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID));
849 if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; 610 if (!params->dev)
611 return -ENOTSUPP;
850 612
851 /* 613 /*
852 * we need more memory: 614 * we need more memory:
@@ -877,9 +639,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
877 } else 639 } else
878 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); 640 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
879 641
880 if (rndis_per_dev_params [configNr].ack) 642 params->resp_avail(params->v);
881 rndis_per_dev_params [configNr].ack (
882 rndis_per_dev_params [configNr].dev);
883 return 0; 643 return 0;
884} 644}
885 645
@@ -888,6 +648,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
888 u32 BufLength, BufOffset; 648 u32 BufLength, BufOffset;
889 rndis_set_cmplt_type *resp; 649 rndis_set_cmplt_type *resp;
890 rndis_resp_t *r; 650 rndis_resp_t *r;
651 struct rndis_params *params = rndis_per_dev_params + configNr;
891 652
892 r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); 653 r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
893 if (!r) 654 if (!r)
@@ -897,7 +658,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
897 BufLength = le32_to_cpu (buf->InformationBufferLength); 658 BufLength = le32_to_cpu (buf->InformationBufferLength);
898 BufOffset = le32_to_cpu (buf->InformationBufferOffset); 659 BufOffset = le32_to_cpu (buf->InformationBufferOffset);
899 660
900#ifdef VERBOSE 661#ifdef VERBOSE_DEBUG
901 DBG("%s: Length: %d\n", __func__, BufLength); 662 DBG("%s: Length: %d\n", __func__, BufLength);
902 DBG("%s: Offset: %d\n", __func__, BufOffset); 663 DBG("%s: Offset: %d\n", __func__, BufOffset);
903 DBG("%s: InfoBuffer: ", __func__); 664 DBG("%s: InfoBuffer: ", __func__);
@@ -918,10 +679,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
918 else 679 else
919 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); 680 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
920 681
921 if (rndis_per_dev_params [configNr].ack) 682 params->resp_avail(params->v);
922 rndis_per_dev_params [configNr].ack (
923 rndis_per_dev_params [configNr].dev);
924
925 return 0; 683 return 0;
926} 684}
927 685
@@ -929,6 +687,7 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
929{ 687{
930 rndis_reset_cmplt_type *resp; 688 rndis_reset_cmplt_type *resp;
931 rndis_resp_t *r; 689 rndis_resp_t *r;
690 struct rndis_params *params = rndis_per_dev_params + configNr;
932 691
933 r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type)); 692 r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
934 if (!r) 693 if (!r)
@@ -941,10 +700,7 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
941 /* resent information */ 700 /* resent information */
942 resp->AddressingReset = __constant_cpu_to_le32 (1); 701 resp->AddressingReset = __constant_cpu_to_le32 (1);
943 702
944 if (rndis_per_dev_params [configNr].ack) 703 params->resp_avail(params->v);
945 rndis_per_dev_params [configNr].ack (
946 rndis_per_dev_params [configNr].dev);
947
948 return 0; 704 return 0;
949} 705}
950 706
@@ -953,6 +709,7 @@ static int rndis_keepalive_response (int configNr,
953{ 709{
954 rndis_keepalive_cmplt_type *resp; 710 rndis_keepalive_cmplt_type *resp;
955 rndis_resp_t *r; 711 rndis_resp_t *r;
712 struct rndis_params *params = rndis_per_dev_params + configNr;
956 713
957 /* host "should" check only in RNDIS_DATA_INITIALIZED state */ 714 /* host "should" check only in RNDIS_DATA_INITIALIZED state */
958 715
@@ -967,10 +724,7 @@ static int rndis_keepalive_response (int configNr,
967 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ 724 resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
968 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); 725 resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
969 726
970 if (rndis_per_dev_params [configNr].ack) 727 params->resp_avail(params->v);
971 rndis_per_dev_params [configNr].ack (
972 rndis_per_dev_params [configNr].dev);
973
974 return 0; 728 return 0;
975} 729}
976 730
@@ -982,8 +736,9 @@ static int rndis_indicate_status_msg (int configNr, u32 status)
982{ 736{
983 rndis_indicate_status_msg_type *resp; 737 rndis_indicate_status_msg_type *resp;
984 rndis_resp_t *r; 738 rndis_resp_t *r;
739 struct rndis_params *params = rndis_per_dev_params + configNr;
985 740
986 if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED) 741 if (params->state == RNDIS_UNINITIALIZED)
987 return -ENOTSUPP; 742 return -ENOTSUPP;
988 743
989 r = rndis_add_response (configNr, 744 r = rndis_add_response (configNr,
@@ -999,9 +754,7 @@ static int rndis_indicate_status_msg (int configNr, u32 status)
999 resp->StatusBufferLength = __constant_cpu_to_le32 (0); 754 resp->StatusBufferLength = __constant_cpu_to_le32 (0);
1000 resp->StatusBufferOffset = __constant_cpu_to_le32 (0); 755 resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
1001 756
1002 if (rndis_per_dev_params [configNr].ack) 757 params->resp_avail(params->v);
1003 rndis_per_dev_params [configNr].ack (
1004 rndis_per_dev_params [configNr].dev);
1005 return 0; 758 return 0;
1006} 759}
1007 760
@@ -1028,7 +781,6 @@ void rndis_uninit (int configNr)
1028 781
1029 if (configNr >= RNDIS_MAX_CONFIGS) 782 if (configNr >= RNDIS_MAX_CONFIGS)
1030 return; 783 return;
1031 rndis_per_dev_params [configNr].used = 0;
1032 rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED; 784 rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;
1033 785
1034 /* drain the response queue */ 786 /* drain the response queue */
@@ -1141,21 +893,25 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
1141 return -ENOTSUPP; 893 return -ENOTSUPP;
1142} 894}
1143 895
1144int rndis_register (int (* rndis_control_ack) (struct net_device *)) 896int rndis_register(void (*resp_avail)(void *v), void *v)
1145{ 897{
1146 u8 i; 898 u8 i;
1147 899
900 if (!resp_avail)
901 return -EINVAL;
902
1148 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) { 903 for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
1149 if (!rndis_per_dev_params [i].used) { 904 if (!rndis_per_dev_params [i].used) {
1150 rndis_per_dev_params [i].used = 1; 905 rndis_per_dev_params [i].used = 1;
1151 rndis_per_dev_params [i].ack = rndis_control_ack; 906 rndis_per_dev_params [i].resp_avail = resp_avail;
907 rndis_per_dev_params [i].v = v;
1152 DBG("%s: configNr = %d\n", __func__, i); 908 DBG("%s: configNr = %d\n", __func__, i);
1153 return i; 909 return i;
1154 } 910 }
1155 } 911 }
1156 DBG("failed\n"); 912 DBG("failed\n");
1157 913
1158 return -1; 914 return -ENODEV;
1159} 915}
1160 916
1161void rndis_deregister (int configNr) 917void rndis_deregister (int configNr)
@@ -1168,16 +924,14 @@ void rndis_deregister (int configNr)
1168 return; 924 return;
1169} 925}
1170 926
1171int rndis_set_param_dev (u8 configNr, struct net_device *dev, 927int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
1172 struct net_device_stats *stats,
1173 u16 *cdc_filter)
1174{ 928{
1175 DBG("%s:\n", __func__ ); 929 DBG("%s:\n", __func__ );
1176 if (!dev || !stats) return -1; 930 if (!dev)
931 return -EINVAL;
1177 if (configNr >= RNDIS_MAX_CONFIGS) return -1; 932 if (configNr >= RNDIS_MAX_CONFIGS) return -1;
1178 933
1179 rndis_per_dev_params [configNr].dev = dev; 934 rndis_per_dev_params [configNr].dev = dev;
1180 rndis_per_dev_params [configNr].stats = stats;
1181 rndis_per_dev_params [configNr].filter = cdc_filter; 935 rndis_per_dev_params [configNr].filter = cdc_filter;
1182 936
1183 return 0; 937 return 0;
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
index b917b4f34ea8..aac61dfe0f03 100644
--- a/drivers/usb/gadget/rndis.h
+++ b/drivers/usb/gadget/rndis.h
@@ -233,20 +233,19 @@ typedef struct rndis_params
233 const u8 *host_mac; 233 const u8 *host_mac;
234 u16 *filter; 234 u16 *filter;
235 struct net_device *dev; 235 struct net_device *dev;
236 struct net_device_stats *stats;
237 236
238 u32 vendorID; 237 u32 vendorID;
239 const char *vendorDescr; 238 const char *vendorDescr;
240 int (*ack) (struct net_device *); 239 void (*resp_avail)(void *v);
240 void *v;
241 struct list_head resp_queue; 241 struct list_head resp_queue;
242} rndis_params; 242} rndis_params;
243 243
244/* RNDIS Message parser and other useless functions */ 244/* RNDIS Message parser and other useless functions */
245int rndis_msg_parser (u8 configNr, u8 *buf); 245int rndis_msg_parser (u8 configNr, u8 *buf);
246int rndis_register (int (*rndis_control_ack) (struct net_device *)); 246int rndis_register(void (*resp_avail)(void *v), void *v);
247void rndis_deregister (int configNr); 247void rndis_deregister (int configNr);
248int rndis_set_param_dev (u8 configNr, struct net_device *dev, 248int rndis_set_param_dev (u8 configNr, struct net_device *dev,
249 struct net_device_stats *stats,
250 u16 *cdc_filter); 249 u16 *cdc_filter);
251int rndis_set_param_vendor (u8 configNr, u32 vendorID, 250int rndis_set_param_vendor (u8 configNr, u32 vendorID,
252 const char *vendorDescr); 251 const char *vendorDescr);