aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
authorAhmed S. Darwish <ahmed.darwish@valeo.com>2015-03-15 11:03:38 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2015-03-22 13:14:49 -0400
commit082d70b6142f623c10f7a032d9b63a2399fb4ded (patch)
tree5f2e845a45b9829a2f201e777cd89fefc4bbbdb1 /drivers/net/can
parentf40bff4239d45ac061044a8a79cf6868c62df345 (diff)
can: kvaser_usb: Comply with firmware max tx URBs value
Current driver code arbitrarily assumes a max outstanding tx value of 16 parallel transmissions. Meanwhile, the device firmware provides its actual maximum inside its reply to the CMD_GET_SOFTWARE_INFO message. Under heavy tx traffic, if the interleaved transmissions count increases above the limit reported by firmware, the firmware breaks up badly, reports a massive list of internal errors, and the candump traces hardly matches the actual frames sent and received. On the other hand, in certain models, the firmware can support up to 48 tx URBs instead of just 16, increasing the driver throughput by two-fold and reducing the possibility of -ENOBUFs. Thus dynamically set the driver's max tx URBs value according to firmware replies. Signed-off-by: Ahmed S. Darwish <ahmed.darwish@valeo.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/usb/kvaser_usb.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index e97a08ce0b90..2f9733a8e125 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -25,7 +25,6 @@
25#include <linux/can/dev.h> 25#include <linux/can/dev.h>
26#include <linux/can/error.h> 26#include <linux/can/error.h>
27 27
28#define MAX_TX_URBS 16
29#define MAX_RX_URBS 4 28#define MAX_RX_URBS 4
30#define START_TIMEOUT 1000 /* msecs */ 29#define START_TIMEOUT 1000 /* msecs */
31#define STOP_TIMEOUT 1000 /* msecs */ 30#define STOP_TIMEOUT 1000 /* msecs */
@@ -443,6 +442,7 @@ struct kvaser_usb_error_summary {
443 }; 442 };
444}; 443};
445 444
445/* Context for an outstanding, not yet ACKed, transmission */
446struct kvaser_usb_tx_urb_context { 446struct kvaser_usb_tx_urb_context {
447 struct kvaser_usb_net_priv *priv; 447 struct kvaser_usb_net_priv *priv;
448 u32 echo_index; 448 u32 echo_index;
@@ -456,8 +456,13 @@ struct kvaser_usb {
456 struct usb_endpoint_descriptor *bulk_in, *bulk_out; 456 struct usb_endpoint_descriptor *bulk_in, *bulk_out;
457 struct usb_anchor rx_submitted; 457 struct usb_anchor rx_submitted;
458 458
459 /* @max_tx_urbs: Firmware-reported maximum number of oustanding,
460 * not yet ACKed, transmissions on this device. This value is
461 * also used as a sentinel for marking free tx contexts.
462 */
459 u32 fw_version; 463 u32 fw_version;
460 unsigned int nchannels; 464 unsigned int nchannels;
465 unsigned int max_tx_urbs;
461 enum kvaser_usb_family family; 466 enum kvaser_usb_family family;
462 467
463 bool rxinitdone; 468 bool rxinitdone;
@@ -467,19 +472,18 @@ struct kvaser_usb {
467 472
468struct kvaser_usb_net_priv { 473struct kvaser_usb_net_priv {
469 struct can_priv can; 474 struct can_priv can;
470 475 struct can_berr_counter bec;
471 spinlock_t tx_contexts_lock;
472 int active_tx_contexts;
473 struct kvaser_usb_tx_urb_context tx_contexts[MAX_TX_URBS];
474
475 struct usb_anchor tx_submitted;
476 struct completion start_comp, stop_comp;
477 476
478 struct kvaser_usb *dev; 477 struct kvaser_usb *dev;
479 struct net_device *netdev; 478 struct net_device *netdev;
480 int channel; 479 int channel;
481 480
482 struct can_berr_counter bec; 481 struct completion start_comp, stop_comp;
482 struct usb_anchor tx_submitted;
483
484 spinlock_t tx_contexts_lock;
485 int active_tx_contexts;
486 struct kvaser_usb_tx_urb_context tx_contexts[];
483}; 487};
484 488
485static const struct usb_device_id kvaser_usb_table[] = { 489static const struct usb_device_id kvaser_usb_table[] = {
@@ -657,9 +661,13 @@ static int kvaser_usb_get_software_info(struct kvaser_usb *dev)
657 switch (dev->family) { 661 switch (dev->family) {
658 case KVASER_LEAF: 662 case KVASER_LEAF:
659 dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version); 663 dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version);
664 dev->max_tx_urbs =
665 le16_to_cpu(msg.u.leaf.softinfo.max_outstanding_tx);
660 break; 666 break;
661 case KVASER_USBCAN: 667 case KVASER_USBCAN:
662 dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version); 668 dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version);
669 dev->max_tx_urbs =
670 le16_to_cpu(msg.u.usbcan.softinfo.max_outstanding_tx);
663 break; 671 break;
664 } 672 }
665 673
@@ -715,7 +723,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
715 723
716 stats = &priv->netdev->stats; 724 stats = &priv->netdev->stats;
717 725
718 context = &priv->tx_contexts[tid % MAX_TX_URBS]; 726 context = &priv->tx_contexts[tid % dev->max_tx_urbs];
719 727
720 /* Sometimes the state change doesn't come after a bus-off event */ 728 /* Sometimes the state change doesn't come after a bus-off event */
721 if (priv->can.restart_ms && 729 if (priv->can.restart_ms &&
@@ -744,7 +752,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
744 spin_lock_irqsave(&priv->tx_contexts_lock, flags); 752 spin_lock_irqsave(&priv->tx_contexts_lock, flags);
745 753
746 can_get_echo_skb(priv->netdev, context->echo_index); 754 can_get_echo_skb(priv->netdev, context->echo_index);
747 context->echo_index = MAX_TX_URBS; 755 context->echo_index = dev->max_tx_urbs;
748 --priv->active_tx_contexts; 756 --priv->active_tx_contexts;
749 netif_wake_queue(priv->netdev); 757 netif_wake_queue(priv->netdev);
750 758
@@ -1512,11 +1520,13 @@ error:
1512 1520
1513static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv) 1521static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv)
1514{ 1522{
1515 int i; 1523 int i, max_tx_urbs;
1524
1525 max_tx_urbs = priv->dev->max_tx_urbs;
1516 1526
1517 priv->active_tx_contexts = 0; 1527 priv->active_tx_contexts = 0;
1518 for (i = 0; i < MAX_TX_URBS; i++) 1528 for (i = 0; i < max_tx_urbs; i++)
1519 priv->tx_contexts[i].echo_index = MAX_TX_URBS; 1529 priv->tx_contexts[i].echo_index = max_tx_urbs;
1520} 1530}
1521 1531
1522/* This method might sleep. Do not call it in the atomic context 1532/* This method might sleep. Do not call it in the atomic context
@@ -1702,14 +1712,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
1702 *msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME; 1712 *msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME;
1703 1713
1704 spin_lock_irqsave(&priv->tx_contexts_lock, flags); 1714 spin_lock_irqsave(&priv->tx_contexts_lock, flags);
1705 for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) { 1715 for (i = 0; i < dev->max_tx_urbs; i++) {
1706 if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { 1716 if (priv->tx_contexts[i].echo_index == dev->max_tx_urbs) {
1707 context = &priv->tx_contexts[i]; 1717 context = &priv->tx_contexts[i];
1708 1718
1709 context->echo_index = i; 1719 context->echo_index = i;
1710 can_put_echo_skb(skb, netdev, context->echo_index); 1720 can_put_echo_skb(skb, netdev, context->echo_index);
1711 ++priv->active_tx_contexts; 1721 ++priv->active_tx_contexts;
1712 if (priv->active_tx_contexts >= MAX_TX_URBS) 1722 if (priv->active_tx_contexts >= dev->max_tx_urbs)
1713 netif_stop_queue(netdev); 1723 netif_stop_queue(netdev);
1714 1724
1715 break; 1725 break;
@@ -1743,7 +1753,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
1743 spin_lock_irqsave(&priv->tx_contexts_lock, flags); 1753 spin_lock_irqsave(&priv->tx_contexts_lock, flags);
1744 1754
1745 can_free_echo_skb(netdev, context->echo_index); 1755 can_free_echo_skb(netdev, context->echo_index);
1746 context->echo_index = MAX_TX_URBS; 1756 context->echo_index = dev->max_tx_urbs;
1747 --priv->active_tx_contexts; 1757 --priv->active_tx_contexts;
1748 netif_wake_queue(netdev); 1758 netif_wake_queue(netdev);
1749 1759
@@ -1881,7 +1891,9 @@ static int kvaser_usb_init_one(struct usb_interface *intf,
1881 if (err) 1891 if (err)
1882 return err; 1892 return err;
1883 1893
1884 netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); 1894 netdev = alloc_candev(sizeof(*priv) +
1895 dev->max_tx_urbs * sizeof(*priv->tx_contexts),
1896 dev->max_tx_urbs);
1885 if (!netdev) { 1897 if (!netdev) {
1886 dev_err(&intf->dev, "Cannot alloc candev\n"); 1898 dev_err(&intf->dev, "Cannot alloc candev\n");
1887 return -ENOMEM; 1899 return -ENOMEM;
@@ -2009,6 +2021,13 @@ static int kvaser_usb_probe(struct usb_interface *intf,
2009 return err; 2021 return err;
2010 } 2022 }
2011 2023
2024 dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n",
2025 ((dev->fw_version >> 24) & 0xff),
2026 ((dev->fw_version >> 16) & 0xff),
2027 (dev->fw_version & 0xffff));
2028
2029 dev_dbg(&intf->dev, "Max oustanding tx = %d URBs\n", dev->max_tx_urbs);
2030
2012 err = kvaser_usb_get_card_info(dev); 2031 err = kvaser_usb_get_card_info(dev);
2013 if (err) { 2032 if (err) {
2014 dev_err(&intf->dev, 2033 dev_err(&intf->dev,
@@ -2016,11 +2035,6 @@ static int kvaser_usb_probe(struct usb_interface *intf,
2016 return err; 2035 return err;
2017 } 2036 }
2018 2037
2019 dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n",
2020 ((dev->fw_version >> 24) & 0xff),
2021 ((dev->fw_version >> 16) & 0xff),
2022 (dev->fw_version & 0xffff));
2023
2024 for (i = 0; i < dev->nchannels; i++) { 2038 for (i = 0; i < dev->nchannels; i++) {
2025 err = kvaser_usb_init_one(intf, id, i); 2039 err = kvaser_usb_init_one(intf, id, i);
2026 if (err) { 2040 if (err) {