summaryrefslogtreecommitdiffstats
path: root/include/linux/can
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/can')
-rw-r--r--include/linux/can/dev.h9
-rw-r--r--include/linux/can/skb.h38
2 files changed, 45 insertions, 2 deletions
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index fb0ab651a041..3ce5e526525f 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -33,8 +33,9 @@ enum can_mode {
struct can_priv {
struct can_device_stats can_stats;
- struct can_bittiming bittiming;
- const struct can_bittiming_const *bittiming_const;
+ struct can_bittiming bittiming, data_bittiming;
+ const struct can_bittiming_const *bittiming_const,
+ *data_bittiming_const;
struct can_clock clock;
enum can_state state;
@@ -45,6 +46,7 @@ struct can_priv {
struct timer_list restart_timer;
int (*do_set_bittiming)(struct net_device *dev);
+ int (*do_set_data_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);
@@ -111,6 +113,7 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
int open_candev(struct net_device *dev);
void close_candev(struct net_device *dev);
+int can_change_mtu(struct net_device *dev, int new_mtu);
int register_candev(struct net_device *dev);
void unregister_candev(struct net_device *dev);
@@ -124,6 +127,8 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
void can_free_echo_skb(struct net_device *dev, unsigned int idx);
struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
+struct sk_buff *alloc_canfd_skb(struct net_device *dev,
+ struct canfd_frame **cfd);
struct sk_buff *alloc_can_err_skb(struct net_device *dev,
struct can_frame **cf);
diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h
index 2f0543f7510c..f9bbbb472663 100644
--- a/include/linux/can/skb.h
+++ b/include/linux/can/skb.h
@@ -11,7 +11,9 @@
#define CAN_SKB_H
#include <linux/types.h>
+#include <linux/skbuff.h>
#include <linux/can.h>
+#include <net/sock.h>
/*
* The struct can_skb_priv is used to transport additional information along
@@ -42,4 +44,40 @@ static inline void can_skb_reserve(struct sk_buff *skb)
skb_reserve(skb, sizeof(struct can_skb_priv));
}
+static inline void can_skb_destructor(struct sk_buff *skb)
+{
+ sock_put(skb->sk);
+}
+
+static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk)
+{
+ if (sk) {
+ sock_hold(sk);
+ skb->destructor = can_skb_destructor;
+ skb->sk = sk;
+ }
+}
+
+/*
+ * returns an unshared skb owned by the original sock to be echo'ed back
+ */
+static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb)
+{
+ if (skb_shared(skb)) {
+ struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+
+ if (likely(nskb)) {
+ can_skb_set_owner(nskb, skb->sk);
+ consume_skb(skb);
+ return nskb;
+ } else {
+ kfree_skb(skb);
+ return NULL;
+ }
+ }
+
+ /* we can assume to have an unshared skb with proper owner */
+ return skb;
+}
+
#endif /* CAN_SKB_H */
OpenPOWER on IntegriCloud