]> rtime.felk.cvut.cz Git - socketcan-devel.git/commitdiff
can: make the number of echo skb's configurable
authorwolf <wolf@030b6a49-0b11-0410-94ab-b0dab22257f2>
Tue, 22 Sep 2009 08:08:15 +0000 (08:08 +0000)
committerwolf <wolf@030b6a49-0b11-0410-94ab-b0dab22257f2>
Tue, 22 Sep 2009 08:08:15 +0000 (08:08 +0000)
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, via:

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

The drivers have been adapted accordingly. Please check if the
value of echo_skb_max is OK for your driver.

Signed-off-by: Kurt Van Dijck <kurt.van.dijck@eia.be>
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
git-svn-id: svn://svn.berlios.de//socketcan/trunk@1061 030b6a49-0b11-0410-94ab-b0dab22257f2

13 files changed:
kernel/2.6/drivers/net/can/at91_can.c
kernel/2.6/drivers/net/can/cc770/cc770.c
kernel/2.6/drivers/net/can/cc770/cc770.h
kernel/2.6/drivers/net/can/dev.c
kernel/2.6/drivers/net/can/ems_usb.c
kernel/2.6/drivers/net/can/esd_pci331.c
kernel/2.6/drivers/net/can/mcp251x.c
kernel/2.6/drivers/net/can/mscan/mscan.c
kernel/2.6/drivers/net/can/sja1000/sja1000.c
kernel/2.6/drivers/net/can/sja1000/sja1000.h
kernel/2.6/drivers/net/can/softing/softing_main.c
kernel/2.6/include/linux/can/dev.h
kernel/2.6/include/socketcan/can/dev.h

index 37c9107006f2a85cf43ad1b7bac74c600f55271c..35aa90ca28f5dc5f27bb4d3bfd232a41e35feb64 100644 (file)
@@ -1094,7 +1094,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;
index e6eee6b403b06650b3185b5e1b0aa8d5ad771a45..c1130671f53d391b8a1cb30098043205a1c2329b 100644 (file)
@@ -862,7 +862,8 @@ struct net_device *alloc_cc770dev(int sizeof_priv)
        struct net_device *dev;
        struct cc770_priv *priv;
 
-       dev = alloc_candev(sizeof(struct cc770_priv) + sizeof_priv);
+       dev = alloc_candev(sizeof(struct cc770_priv) + sizeof_priv,
+                          CC770_ECHO_SKB_MAX);
        if (!dev)
                return NULL;
 
index 1855c53dc0c5b086d79316e8f5f1001a39ecd21a..ded17c4177e0d32e5bd4cc0faf163164c032fd1c 100644 (file)
@@ -188,6 +188,8 @@ struct cc770_regs {
 #define CC770_IO_SIZE  0x100
 #define CC770_MAX_IRQ  20      /* max. number of interrupts handled in ISR */
 
+#define CC770_ECHO_SKB_MAX     1
+
 #define cc770_read_reg(priv, member)                                   \
        priv->read_reg(priv, offsetof(struct cc770_regs, member))
 
@@ -197,9 +199,9 @@ struct cc770_regs {
 /*
  * Message objects and flags used by this driver
  */
-#define CC770_OBJ_FLAG_RX  0x01
-#define CC770_OBJ_FLAG_RTR 0x02
-#define CC770_OBJ_FLAG_EFF 0x04
+#define CC770_OBJ_FLAG_RX      0x01
+#define CC770_OBJ_FLAG_RTR     0x02
+#define CC770_OBJ_FLAG_EFF     0x04
 
 enum {
        CC770_OBJ_RX0 = 0,      /* for receiving normal messages */
index cc13c968c54915f58e483d48511aa74cbc20ff3e..fd3d06e7fe6adb6aa016bf86048b7afb6152431e 100644 (file)
@@ -272,7 +272,7 @@ static void can_flush_echo_skb(struct net_device *dev)
 #endif
        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;
@@ -289,10 +289,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);
@@ -338,10 +341,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;
@@ -354,10 +359,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;
@@ -492,17 +499,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);
index 7fb9275a962152b08255552742d457b7f8f79538..2b106cb35c5d7c9f87f1a1f4556fc62c1a1db9f6 100644 (file)
@@ -226,7 +226,7 @@ MODULE_DEVICE_TABLE(usb, ems_usb_table);
 #define CPC_HEADER_SIZE 4
 
 #define MAX_RX_URBS 10
-#define MAX_TX_URBS CAN_ECHO_SKB_MAX
+#define MAX_TX_URBS 4
 
 struct ems_usb;
 
@@ -1018,7 +1018,7 @@ static int ems_usb_probe(struct usb_interface *intf,
        struct ems_usb *dev;
        int i, err;
 
-       netdev = alloc_candev(sizeof(struct ems_usb));
+       netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS);
        if (!netdev) {
                dev_err(ND2D(netdev), "Couldn't alloc candev\n");
                return -ENOMEM;
index 16aac283e5ef617fbdc43f8344d88d5d81b43814..5fe879d7ab0e10f421be1fb943c418634e3a5764 100644 (file)
@@ -99,6 +99,8 @@ MODULE_SUPPORTED_DEVICE("esd CAN-PCI/331, CAN-CPCI/331, CAN-PMC/331");
 #define ESD331_I20_BOARD2              20
 #define ESD331_I20_FAST                        21
 
+#define ESD331_ECHO_SKB_MAX            1
+
 static struct pci_device_id esd331_pci_tbl[] = {
        {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
        PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI331},
@@ -785,7 +787,7 @@ static struct net_device *__devinit esd331_pci_add_chan(struct pci_dev *pdev,
        struct esd331_priv *priv;
        int err;
 
-       dev = alloc_candev(sizeof(*priv));
+       dev = alloc_candev(sizeof(*priv), ESD331_ECHO_SKB_MAX);
        if (dev == NULL)
                return ERR_PTR(-ENOMEM);
 
index 80e1a33170bce7b7d1ea2f6ae75721dd36392fb6..b08c9237a61635f846ca8734f97d8b0ea26f4127 100644 (file)
 #define SPI_TRANSFER_BUF_LEN   (2*(6 + CAN_FRAME_MAX_DATA_LEN))
 #define CAN_FRAME_MAX_BITS     128
 
+#define TX_ECHO_SKB_MAX        1
+
 #define DEVICE_NAME "mcp251x"
 
 static int mcp251x_enable_dma; /* Enable SPI DMA. Default: 0 (Off) */
@@ -946,7 +948,7 @@ static struct net_device *alloc_mcp251x_netdev(int sizeof_priv,
        struct net_device *net;
        struct mcp251x_priv *priv;
 
-       net = alloc_candev(sizeof_priv);
+       net = alloc_candev(sizeof_priv, TX_ECHO_SKB_MAX);
        if (!net)
                return NULL;
 
index fa5d907b6f486cb3c44f82426f1e46ed7e7777f7..894518e490553f79a436637db5dc85a3281d4bd5 100644 (file)
@@ -46,6 +46,7 @@ RCSID("$Id$");
 #define MSCAN_INIT_MODE                (MSCAN_INITRQ | MSCAN_SLPRQ)
 #define MSCAN_POWEROFF_MODE    (MSCAN_CSWAI | MSCAN_SLPRQ)
 #define MSCAN_SET_MODE_RETRIES 255
+#define MSCAN_ECHO_SKB_MAX     3
 
 #define BTR0_BRP_MASK          0x3f
 #define BTR0_SJW_SHIFT         6
@@ -729,7 +730,7 @@ struct net_device *alloc_mscandev(void)
        struct mscan_priv *priv;
        int i;
 
-       dev = alloc_candev(sizeof(struct mscan_priv));
+       dev = alloc_candev(sizeof(struct mscan_priv), MSCAN_ECHO_SKB_MAX);
        if (!dev)
                return NULL;
        priv = netdev_priv(dev);
index 54f65e76d5061406ef45326eae6406aa4f712335..994de09e0ab75154810bf6b5efbf58d803ad557b 100644 (file)
@@ -600,7 +600,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;
 
index 7a35f4c3f98dbd07f2e1217e0133b393b41a4718..02aeb1811c6dd26b2fe7e800ebd61c0cdebfa807 100644 (file)
@@ -50,6 +50,8 @@
 #include <socketcan/can/dev.h>
 #include <socketcan/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) */
index a9a45c37db267f8a7f7187a12ecbd29627c21fb8..cb1fd75648a54b3052916eb547ac16ec9da6e63a 100644 (file)
@@ -33,6 +33,8 @@
 #error This driver does not support Kernel versions < 2.6.23
 #endif
 
+#define TX_ECHO_SKB_MAX 4
+
 /*
  * test is a specific CAN netdev
  * is online (ie. up 'n running, not sleeping, not busoff
@@ -74,7 +76,7 @@ static netdev_tx_t netdev_start_xmit(struct sk_buff *skb,
                goto xmit_done;
        if (card->tx.pending >= TXMAX)
                goto xmit_done;
-       if (priv->tx.pending >= CAN_ECHO_SKB_MAX)
+       if (priv->tx.pending >= TX_ECHO_SKB_MAX)
                goto xmit_done;
        fifo_wr = card->dpram.tx->wr;
        if (fifo_wr == card->dpram.tx->rd)
@@ -112,7 +114,7 @@ static netdev_tx_t netdev_start_xmit(struct sk_buff *skb,
        ++priv->tx.pending;
        can_put_echo_skb(skb, dev, priv->tx.echo_put);
        ++priv->tx.echo_put;
-       if (priv->tx.echo_put >= CAN_ECHO_SKB_MAX)
+       if (priv->tx.echo_put >= TX_ECHO_SKB_MAX)
                priv->tx.echo_put = 0;
        /* can_put_echo_skb() saves the skb, safe to return TX_OK */
        ret = NETDEV_TX_OK;
@@ -324,7 +326,7 @@ static int softing_dev_svc_once(struct softing *card)
                                skb->tstamp = ktime;
                        can_get_echo_skb(bus->netdev, bus->tx.echo_get);
                        ++bus->tx.echo_get;
-                       if (bus->tx.echo_get >= CAN_ECHO_SKB_MAX)
+                       if (bus->tx.echo_get >= TX_ECHO_SKB_MAX)
                                bus->tx.echo_get = 0;
                        if (bus->tx.pending)
                                --bus->tx.pending;
@@ -367,7 +369,7 @@ static void softing_dev_svc(unsigned long param)
                if (!canif_is_active(bus->netdev))
                        /* it makes no sense to wake dead busses */
                        continue;
-               if (bus->tx.pending >= CAN_ECHO_SKB_MAX)
+               if (bus->tx.pending >= TX_ECHO_SKB_MAX)
                        continue;
                netif_wake_queue(bus->netdev);
        }
@@ -632,7 +634,7 @@ static struct softing_priv *mk_netdev(struct softing *card, u16 chip_id)
        struct net_device *ndev;
        struct softing_priv *priv;
 
-       ndev = alloc_candev(sizeof(*priv));
+       ndev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
        if (!ndev) {
                dev_alert(card->dev, "alloc_candev failed\n");
                return 0;
index fbe374129cabc406bed2949ec08eb65b140e244b..6d693b1ec6e5e6ad5b4b4f80b231105dc7bdd0a6 100644 (file)
@@ -32,8 +32,6 @@ enum can_mode {
 /*
  * CAN common private data
  */
-#define CAN_ECHO_SKB_MAX  4
-
 struct can_priv {
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
        struct net_device_stats net_stats;
@@ -50,12 +48,13 @@ struct can_priv {
        int restart_ms;
        struct timer_list restart_timer;
 
-       struct sk_buff *echo_skb[CAN_ECHO_SKB_MAX];
-
        int (*do_set_bittiming)(struct net_device *dev);
        int (*do_set_mode)(struct net_device *dev, enum can_mode mode);
        int (*do_get_state)(const struct net_device *dev,
                            enum can_state *state);
+
+       unsigned int echo_skb_max;
+       struct sk_buff **echo_skb;
 };
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
@@ -72,7 +71,7 @@ struct can_priv {
 struct net_device_stats *can_get_stats(struct net_device *dev);
 #endif
 
-struct net_device *alloc_candev(int sizeof_priv);
+struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max);
 void free_candev(struct net_device *dev);
 
 int open_candev(struct net_device *dev);
@@ -84,8 +83,9 @@ void unregister_candev(struct net_device *dev);
 int can_restart_now(struct net_device *dev);
 void can_bus_off(struct net_device *dev);
 
-void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx);
-void can_get_echo_skb(struct net_device *dev, int idx);
-void can_free_echo_skb(struct net_device *dev, int idx);
+void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
+                     unsigned int idx);
+void can_get_echo_skb(struct net_device *dev, unsigned int idx);
+void can_free_echo_skb(struct net_device *dev, unsigned int idx);
 
 #endif /* CAN_DEV_H */
index 933a575e0b91d7ff15fb86ae0704d54e1429b363..617037c3a4cbcf496c9e2d5f4aa5735cb6497f1c 100644 (file)
@@ -32,8 +32,6 @@ enum can_mode {
 /*
  * CAN common private data
  */
-#define CAN_ECHO_SKB_MAX  4
-
 struct can_priv {
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
        struct net_device_stats net_stats;
@@ -50,12 +48,13 @@ struct can_priv {
        int restart_ms;
        struct timer_list restart_timer;
 
-       struct sk_buff *echo_skb[CAN_ECHO_SKB_MAX];
-
        int (*do_set_bittiming)(struct net_device *dev);
        int (*do_set_mode)(struct net_device *dev, enum can_mode mode);
        int (*do_get_state)(const struct net_device *dev,
                            enum can_state *state);
+
+       unsigned int echo_skb_max;
+       struct sk_buff **echo_skb;
 };
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
@@ -72,7 +71,7 @@ struct can_priv {
 struct net_device_stats *can_get_stats(struct net_device *dev);
 #endif
 
-struct net_device *alloc_candev(int sizeof_priv);
+struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max);
 void free_candev(struct net_device *dev);
 
 int open_candev(struct net_device *dev);
@@ -84,8 +83,9 @@ void unregister_candev(struct net_device *dev);
 int can_restart_now(struct net_device *dev);
 void can_bus_off(struct net_device *dev);
 
-void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx);
-void can_get_echo_skb(struct net_device *dev, int idx);
-void can_free_echo_skb(struct net_device *dev, int idx);
+void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
+                     unsigned int idx);
+void can_get_echo_skb(struct net_device *dev, unsigned int idx);
+void can_free_echo_skb(struct net_device *dev, unsigned int idx);
 
 #endif /* CAN_DEV_H */