Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6e4bc53 authored by Wolfgang Grandegger's avatar Wolfgang Grandegger Committed by David S. Miller
Browse files

can: make the number of echo skb's configurable



This patch allows the CAN controller driver to define the number of echo
skb's used for the local loopback (echo), as suggested by Kurt Van
Dijck, with the function:

  struct net_device *alloc_candev(int sizeof_priv,
                                  unsigned int echo_skb_max);

The CAN drivers have been adapted accordingly. For the ems_usb driver,
as suggested by Sebastian Haas, the number of echo skb's has been
increased to 10, which improves the transmission performance a lot.

Signed-off-by: default avatarWolfgang Grandegger <wg@grandegger.com>
Signed-off-by: default avatarKurt Van Dijck <kurt.van.dijck@eia.be>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 61321bbd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1087,7 +1087,7 @@ static int __init at91_can_probe(struct platform_device *pdev)
		goto exit_release;
	}

	dev = alloc_candev(sizeof(struct at91_priv));
	dev = alloc_candev(sizeof(struct at91_priv), AT91_MB_TX_NUM);
	if (!dev) {
		err = -ENOMEM;
		goto exit_iounmap;
+26 −6
Original line number Diff line number Diff line
@@ -245,7 +245,7 @@ static void can_flush_echo_skb(struct net_device *dev)
	struct net_device_stats *stats = &dev->stats;
	int i;

	for (i = 0; i < CAN_ECHO_SKB_MAX; i++) {
	for (i = 0; i < priv->echo_skb_max; i++) {
		if (priv->echo_skb[i]) {
			kfree_skb(priv->echo_skb[i]);
			priv->echo_skb[i] = NULL;
@@ -262,10 +262,13 @@ static void can_flush_echo_skb(struct net_device *dev)
 * of the device driver. The driver must protect access to
 * priv->echo_skb, if necessary.
 */
void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx)
void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
		      unsigned int idx)
{
	struct can_priv *priv = netdev_priv(dev);

	BUG_ON(idx >= priv->echo_skb_max);

	/* check flag whether this packet has to be looped back */
	if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
		kfree_skb(skb);
@@ -311,10 +314,12 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
 * is handled in the device driver. The driver must protect
 * access to priv->echo_skb, if necessary.
 */
void can_get_echo_skb(struct net_device *dev, int idx)
void can_get_echo_skb(struct net_device *dev, unsigned int idx)
{
	struct can_priv *priv = netdev_priv(dev);

	BUG_ON(idx >= priv->echo_skb_max);

	if (priv->echo_skb[idx]) {
		netif_rx(priv->echo_skb[idx]);
		priv->echo_skb[idx] = NULL;
@@ -327,10 +332,12 @@ EXPORT_SYMBOL_GPL(can_get_echo_skb);
  *
  * The function is typically called when TX failed.
  */
void can_free_echo_skb(struct net_device *dev, int idx)
void can_free_echo_skb(struct net_device *dev, unsigned int idx)
{
	struct can_priv *priv = netdev_priv(dev);

	BUG_ON(idx >= priv->echo_skb_max);

	if (priv->echo_skb[idx]) {
		kfree_skb(priv->echo_skb[idx]);
		priv->echo_skb[idx] = NULL;
@@ -445,17 +452,30 @@ static void can_setup(struct net_device *dev)
/*
 * Allocate and setup space for the CAN network device
 */
struct net_device *alloc_candev(int sizeof_priv)
struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
{
	struct net_device *dev;
	struct can_priv *priv;
	int size;

	dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
	if (echo_skb_max)
		size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) +
			echo_skb_max * sizeof(struct sk_buff *);
	else
		size = sizeof_priv;

	dev = alloc_netdev(size, "can%d", can_setup);
	if (!dev)
		return NULL;

	priv = netdev_priv(dev);

	if (echo_skb_max) {
		priv->echo_skb_max = echo_skb_max;
		priv->echo_skb = (void *)priv +
			ALIGN(sizeof_priv, sizeof(struct sk_buff *));
	}

	priv->state = CAN_STATE_STOPPED;

	init_timer(&priv->restart_timer);
+2 −1
Original line number Diff line number Diff line
@@ -565,7 +565,8 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
	struct net_device *dev;
	struct sja1000_priv *priv;

	dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv);
	dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv,
		SJA1000_ECHO_SKB_MAX);
	if (!dev)
		return NULL;

+2 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@
#include <linux/can/dev.h>
#include <linux/can/platform/sja1000.h>

#define SJA1000_ECHO_SKB_MAX	1 /* the SJA1000 has one TX buffer object */

#define SJA1000_MAX_IRQ 20	/* max. number of interrupts handled in ISR */

/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
+1 −5
Original line number Diff line number Diff line
@@ -74,10 +74,6 @@ MODULE_VERSION(HECC_MODULE_VERSION);
#define HECC_MB_TX_SHIFT	2 /* as per table above */
#define HECC_MAX_TX_MBOX	BIT(HECC_MB_TX_SHIFT)

#if (HECC_MAX_TX_MBOX > CAN_ECHO_SKB_MAX)
#error "HECC: MAX TX mailboxes should be equal or less than CAN_ECHO_SKB_MAX"
#endif

#define HECC_TX_PRIO_SHIFT	(HECC_MB_TX_SHIFT)
#define HECC_TX_PRIO_MASK	(MAX_TX_PRIO << HECC_MB_TX_SHIFT)
#define HECC_TX_MB_MASK		(HECC_MAX_TX_MBOX - 1)
@@ -902,7 +898,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
		goto probe_exit_free_region;
	}

	ndev = alloc_candev(sizeof(struct ti_hecc_priv));
	ndev = alloc_candev(sizeof(struct ti_hecc_priv), HECC_MAX_TX_MBOX);
	if (!ndev) {
		dev_err(&pdev->dev, "alloc_candev failed\n");
		err = -ENOMEM;
Loading