aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-04-01 13:58:06 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-01 13:58:06 -0400
commitb9600d2d0901cd0f91cb372e72bd53d22f49638d (patch)
tree6684a4fd1345c65a5a91aff272785cd0943d347d
parent8d88c6ebb34c3e54debe81e9b0d81b60411f8179 (diff)
parent79d5eeddd7d23bd4588e370072977928b7075911 (diff)
Merge tag 'linux-can-next-for-4.1-20150401' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next
Marc Kleine-Budde says: ==================== pull-request: can-next 2015-04-01 this is a pull request of 5 patches for net-next/master. There are two patches for the ems_usb driver by Gerhard Uttenthaler and me, which fix sparse endianess warnings. Oliver Hartkopp adds two patches to improve and extend the CAN-ID filter handling on RAW CAN sockets. The last patch is by me, it silences an uninitialized variable warning in the peak_usb driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/networking/can.txt20
-rw-r--r--drivers/net/can/usb/ems_usb.c11
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb_fd.c2
-rw-r--r--include/uapi/linux/can/raw.h1
-rw-r--r--net/can/raw.c50
5 files changed, 74 insertions, 10 deletions
diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt
index 0a2859a8ee7e..5abad1e921ca 100644
--- a/Documentation/networking/can.txt
+++ b/Documentation/networking/can.txt
@@ -22,7 +22,8 @@ This file contains
22 4.1.3 RAW socket option CAN_RAW_LOOPBACK 22 4.1.3 RAW socket option CAN_RAW_LOOPBACK
23 4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS 23 4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS
24 4.1.5 RAW socket option CAN_RAW_FD_FRAMES 24 4.1.5 RAW socket option CAN_RAW_FD_FRAMES
25 4.1.6 RAW socket returned message flags 25 4.1.6 RAW socket option CAN_RAW_JOIN_FILTERS
26 4.1.7 RAW socket returned message flags
26 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) 27 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
27 4.2.1 Broadcast Manager operations 28 4.2.1 Broadcast Manager operations
28 4.2.2 Broadcast Manager message flags 29 4.2.2 Broadcast Manager message flags
@@ -601,7 +602,22 @@ solution for a couple of reasons:
601 CAN FD frames by checking if the device maximum transfer unit is CANFD_MTU. 602 CAN FD frames by checking if the device maximum transfer unit is CANFD_MTU.
602 The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall. 603 The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall.
603 604
604 4.1.6 RAW socket returned message flags 605 4.1.6 RAW socket option CAN_RAW_JOIN_FILTERS
606
607 The CAN_RAW socket can set multiple CAN identifier specific filters that
608 lead to multiple filters in the af_can.c filter processing. These filters
609 are indenpendent from each other which leads to logical OR'ed filters when
610 applied (see 4.1.1).
611
612 This socket option joines the given CAN filters in the way that only CAN
613 frames are passed to user space that matched *all* given CAN filters. The
614 semantic for the applied filters is therefore changed to a logical AND.
615
616 This is useful especially when the filterset is a combination of filters
617 where the CAN_INV_FILTER flag is set in order to notch single CAN IDs or
618 CAN ID ranges from the incoming traffic.
619
620 4.1.7 RAW socket returned message flags
605 621
606 When using recvmsg() call, the msg->msg_flags may contain following flags: 622 When using recvmsg() call, the msg->msg_flags may contain following flags:
607 623
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 9376f5e5b94e..866bac0ae7e9 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -123,7 +123,7 @@ MODULE_LICENSE("GPL v2");
123 * CPC_MSG_TYPE_EXT_CAN_FRAME or CPC_MSG_TYPE_EXT_RTR_FRAME. 123 * CPC_MSG_TYPE_EXT_CAN_FRAME or CPC_MSG_TYPE_EXT_RTR_FRAME.
124 */ 124 */
125struct cpc_can_msg { 125struct cpc_can_msg {
126 u32 id; 126 __le32 id;
127 u8 length; 127 u8 length;
128 u8 msg[8]; 128 u8 msg[8];
129}; 129};
@@ -200,8 +200,8 @@ struct __packed ems_cpc_msg {
200 u8 type; /* type of message */ 200 u8 type; /* type of message */
201 u8 length; /* length of data within union 'msg' */ 201 u8 length; /* length of data within union 'msg' */
202 u8 msgid; /* confirmation handle */ 202 u8 msgid; /* confirmation handle */
203 u32 ts_sec; /* timestamp in seconds */ 203 __le32 ts_sec; /* timestamp in seconds */
204 u32 ts_nsec; /* timestamp in nano seconds */ 204 __le32 ts_nsec; /* timestamp in nano seconds */
205 205
206 union { 206 union {
207 u8 generic[64]; 207 u8 generic[64];
@@ -765,7 +765,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
765 765
766 msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE]; 766 msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE];
767 767
768 msg->msg.can_msg.id = cf->can_id & CAN_ERR_MASK; 768 msg->msg.can_msg.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
769 msg->msg.can_msg.length = cf->can_dlc; 769 msg->msg.can_msg.length = cf->can_dlc;
770 770
771 if (cf->can_id & CAN_RTR_FLAG) { 771 if (cf->can_id & CAN_RTR_FLAG) {
@@ -783,9 +783,6 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
783 msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc; 783 msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc;
784 } 784 }
785 785
786 /* Respect byte order */
787 msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id);
788
789 for (i = 0; i < MAX_TX_URBS; i++) { 786 for (i = 0; i < MAX_TX_URBS; i++) {
790 if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) { 787 if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) {
791 context = &dev->tx_contexts[i]; 788 context = &dev->tx_contexts[i];
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 0bac0f14edc3..00481eeb9924 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -182,7 +182,7 @@ static inline void *pcan_usb_fd_cmd_buffer(struct peak_usb_device *dev)
182static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail) 182static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
183{ 183{
184 void *cmd_head = pcan_usb_fd_cmd_buffer(dev); 184 void *cmd_head = pcan_usb_fd_cmd_buffer(dev);
185 int err; 185 int err = 0;
186 u8 *packet_ptr; 186 u8 *packet_ptr;
187 int i, n = 1, packet_len; 187 int i, n = 1, packet_len;
188 ptrdiff_t cmd_len; 188 ptrdiff_t cmd_len;
diff --git a/include/uapi/linux/can/raw.h b/include/uapi/linux/can/raw.h
index 78ec76fd89a6..8735f1080385 100644
--- a/include/uapi/linux/can/raw.h
+++ b/include/uapi/linux/can/raw.h
@@ -57,6 +57,7 @@ enum {
57 CAN_RAW_LOOPBACK, /* local loopback (default:on) */ 57 CAN_RAW_LOOPBACK, /* local loopback (default:on) */
58 CAN_RAW_RECV_OWN_MSGS, /* receive my own msgs (default:off) */ 58 CAN_RAW_RECV_OWN_MSGS, /* receive my own msgs (default:off) */
59 CAN_RAW_FD_FRAMES, /* allow CAN FD frames (default:off) */ 59 CAN_RAW_FD_FRAMES, /* allow CAN FD frames (default:off) */
60 CAN_RAW_JOIN_FILTERS, /* all filters must match to trigger */
60}; 61};
61 62
62#endif /* !_UAPI_CAN_RAW_H */ 63#endif /* !_UAPI_CAN_RAW_H */
diff --git a/net/can/raw.c b/net/can/raw.c
index 63ffdb0f3a23..31b9748cbb4e 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -74,6 +74,12 @@ MODULE_ALIAS("can-proto-1");
74 * storing the single filter in dfilter, to avoid using dynamic memory. 74 * storing the single filter in dfilter, to avoid using dynamic memory.
75 */ 75 */
76 76
77struct uniqframe {
78 ktime_t tstamp;
79 const struct sk_buff *skb;
80 unsigned int join_rx_count;
81};
82
77struct raw_sock { 83struct raw_sock {
78 struct sock sk; 84 struct sock sk;
79 int bound; 85 int bound;
@@ -82,10 +88,12 @@ struct raw_sock {
82 int loopback; 88 int loopback;
83 int recv_own_msgs; 89 int recv_own_msgs;
84 int fd_frames; 90 int fd_frames;
91 int join_filters;
85 int count; /* number of active filters */ 92 int count; /* number of active filters */
86 struct can_filter dfilter; /* default/single filter */ 93 struct can_filter dfilter; /* default/single filter */
87 struct can_filter *filter; /* pointer to filter(s) */ 94 struct can_filter *filter; /* pointer to filter(s) */
88 can_err_mask_t err_mask; 95 can_err_mask_t err_mask;
96 struct uniqframe __percpu *uniq;
89}; 97};
90 98
91/* 99/*
@@ -123,6 +131,26 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
123 if (!ro->fd_frames && oskb->len != CAN_MTU) 131 if (!ro->fd_frames && oskb->len != CAN_MTU)
124 return; 132 return;
125 133
134 /* eliminate multiple filter matches for the same skb */
135 if (this_cpu_ptr(ro->uniq)->skb == oskb &&
136 ktime_equal(this_cpu_ptr(ro->uniq)->tstamp, oskb->tstamp)) {
137 if (ro->join_filters) {
138 this_cpu_inc(ro->uniq->join_rx_count);
139 /* drop frame until all enabled filters matched */
140 if (this_cpu_ptr(ro->uniq)->join_rx_count < ro->count)
141 return;
142 } else {
143 return;
144 }
145 } else {
146 this_cpu_ptr(ro->uniq)->skb = oskb;
147 this_cpu_ptr(ro->uniq)->tstamp = oskb->tstamp;
148 this_cpu_ptr(ro->uniq)->join_rx_count = 1;
149 /* drop first frame to check all enabled filters? */
150 if (ro->join_filters && ro->count > 1)
151 return;
152 }
153
126 /* clone the given skb to be able to enqueue it into the rcv queue */ 154 /* clone the given skb to be able to enqueue it into the rcv queue */
127 skb = skb_clone(oskb, GFP_ATOMIC); 155 skb = skb_clone(oskb, GFP_ATOMIC);
128 if (!skb) 156 if (!skb)
@@ -296,6 +324,12 @@ static int raw_init(struct sock *sk)
296 ro->loopback = 1; 324 ro->loopback = 1;
297 ro->recv_own_msgs = 0; 325 ro->recv_own_msgs = 0;
298 ro->fd_frames = 0; 326 ro->fd_frames = 0;
327 ro->join_filters = 0;
328
329 /* alloc_percpu provides zero'ed memory */
330 ro->uniq = alloc_percpu(struct uniqframe);
331 if (unlikely(!ro->uniq))
332 return -ENOMEM;
299 333
300 /* set notifier */ 334 /* set notifier */
301 ro->notifier.notifier_call = raw_notifier; 335 ro->notifier.notifier_call = raw_notifier;
@@ -339,6 +373,7 @@ static int raw_release(struct socket *sock)
339 ro->ifindex = 0; 373 ro->ifindex = 0;
340 ro->bound = 0; 374 ro->bound = 0;
341 ro->count = 0; 375 ro->count = 0;
376 free_percpu(ro->uniq);
342 377
343 sock_orphan(sk); 378 sock_orphan(sk);
344 sock->sk = NULL; 379 sock->sk = NULL;
@@ -583,6 +618,15 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
583 618
584 break; 619 break;
585 620
621 case CAN_RAW_JOIN_FILTERS:
622 if (optlen != sizeof(ro->join_filters))
623 return -EINVAL;
624
625 if (copy_from_user(&ro->join_filters, optval, optlen))
626 return -EFAULT;
627
628 break;
629
586 default: 630 default:
587 return -ENOPROTOOPT; 631 return -ENOPROTOOPT;
588 } 632 }
@@ -647,6 +691,12 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
647 val = &ro->fd_frames; 691 val = &ro->fd_frames;
648 break; 692 break;
649 693
694 case CAN_RAW_JOIN_FILTERS:
695 if (len > sizeof(int))
696 len = sizeof(int);
697 val = &ro->join_filters;
698 break;
699
650 default: 700 default:
651 return -ENOPROTOOPT; 701 return -ENOPROTOOPT;
652 } 702 }