diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/ether.c | 24 | ||||
-rw-r--r-- | drivers/usb/gadget/ndis.h | 10 | ||||
-rw-r--r-- | drivers/usb/gadget/rndis.c | 366 | ||||
-rw-r--r-- | drivers/usb/gadget/rndis.h | 7 |
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 | ||
2070 | static int rndis_control_ack (struct net_device *net) | 2070 | static 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) { |
2571 | fail0: | 2569 | fail0: |
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 | ||
729 | update_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 | ||
1144 | int rndis_register (int (* rndis_control_ack) (struct net_device *)) | 896 | int 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 | ||
1161 | void rndis_deregister (int configNr) | 917 | void rndis_deregister (int configNr) |
@@ -1168,16 +924,14 @@ void rndis_deregister (int configNr) | |||
1168 | return; | 924 | return; |
1169 | } | 925 | } |
1170 | 926 | ||
1171 | int rndis_set_param_dev (u8 configNr, struct net_device *dev, | 927 | int 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 */ |
245 | int rndis_msg_parser (u8 configNr, u8 *buf); | 245 | int rndis_msg_parser (u8 configNr, u8 *buf); |
246 | int rndis_register (int (*rndis_control_ack) (struct net_device *)); | 246 | int rndis_register(void (*resp_avail)(void *v), void *v); |
247 | void rndis_deregister (int configNr); | 247 | void rndis_deregister (int configNr); |
248 | int rndis_set_param_dev (u8 configNr, struct net_device *dev, | 248 | int rndis_set_param_dev (u8 configNr, struct net_device *dev, |
249 | struct net_device_stats *stats, | ||
250 | u16 *cdc_filter); | 249 | u16 *cdc_filter); |
251 | int rndis_set_param_vendor (u8 configNr, u32 vendorID, | 250 | int rndis_set_param_vendor (u8 configNr, u32 vendorID, |
252 | const char *vendorDescr); | 251 | const char *vendorDescr); |