aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/dev.c')
-rw-r--r--drivers/net/can/dev.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 0929c7d83e15..ac86be52b461 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -11,6 +11,7 @@
11#include <linux/if_arp.h> 11#include <linux/if_arp.h>
12#include <linux/workqueue.h> 12#include <linux/workqueue.h>
13#include <linux/can.h> 13#include <linux/can.h>
14#include <linux/can/can-ml.h>
14#include <linux/can/dev.h> 15#include <linux/can/dev.h>
15#include <linux/can/skb.h> 16#include <linux/can/skb.h>
16#include <linux/can/netlink.h> 17#include <linux/can/netlink.h>
@@ -713,11 +714,24 @@ struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
713 struct can_priv *priv; 714 struct can_priv *priv;
714 int size; 715 int size;
715 716
717 /* We put the driver's priv, the CAN mid layer priv and the
718 * echo skb into the netdevice's priv. The memory layout for
719 * the netdev_priv is like this:
720 *
721 * +-------------------------+
722 * | driver's priv |
723 * +-------------------------+
724 * | struct can_ml_priv |
725 * +-------------------------+
726 * | array of struct sk_buff |
727 * +-------------------------+
728 */
729
730 size = ALIGN(sizeof_priv, NETDEV_ALIGN) + sizeof(struct can_ml_priv);
731
716 if (echo_skb_max) 732 if (echo_skb_max)
717 size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) + 733 size = ALIGN(size, sizeof(struct sk_buff *)) +
718 echo_skb_max * sizeof(struct sk_buff *); 734 echo_skb_max * sizeof(struct sk_buff *);
719 else
720 size = sizeof_priv;
721 735
722 dev = alloc_netdev_mqs(size, "can%d", NET_NAME_UNKNOWN, can_setup, 736 dev = alloc_netdev_mqs(size, "can%d", NET_NAME_UNKNOWN, can_setup,
723 txqs, rxqs); 737 txqs, rxqs);
@@ -727,10 +741,12 @@ struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
727 priv = netdev_priv(dev); 741 priv = netdev_priv(dev);
728 priv->dev = dev; 742 priv->dev = dev;
729 743
744 dev->ml_priv = (void *)priv + ALIGN(sizeof_priv, NETDEV_ALIGN);
745
730 if (echo_skb_max) { 746 if (echo_skb_max) {
731 priv->echo_skb_max = echo_skb_max; 747 priv->echo_skb_max = echo_skb_max;
732 priv->echo_skb = (void *)priv + 748 priv->echo_skb = (void *)priv +
733 ALIGN(sizeof_priv, sizeof(struct sk_buff *)); 749 (size - echo_skb_max * sizeof(struct sk_buff *));
734 } 750 }
735 751
736 priv->state = CAN_STATE_STOPPED; 752 priv->state = CAN_STATE_STOPPED;