linux-can-next-for-4.1-20150401
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJVG8DxAAoJECte4hHFiupUkFkP+QEDROmDdcYQPRqNgVXvbNxo +uFBI+Y9ttnm+WCR9tu2v2NDuFsbPaD5ckK/idDypSS9tcQWcZqS8odPq9lFYTqu OvfH3lMT82myZf7MT6evn3l6Zwm3UM0fXRxvflpUyFsM8h8quOkhx+ckHK9rjhU7 vEDRDbg1r2xAvQcAm0ACwTCKIxqtf+xnRKwarR+q/1hiHUOmd455cR6uUc+ydAbt 94J4ltnUmpZOgBiNmhZBrD29cheKmwqVEsiv5RcFaRbilJmWM8HFOjsocMAbaz8O hoV8TQbQY1m2fc+sqBlJUr2YYBGnU1jHzhVP9fgAAvhjZGmRXT5zcEorN4m8sGn2 6/slVnkeUyy3wgrmqphk81qd86nTd51gMaI5ixs19eG4epjcQ04ORAZs4zkxVQDo wUNDS1CLdoGztJUjf4+fEjfU9FXXIrBbyXbpXGiNwogXpFCzSj+NNtEyuzaRlSok 72mn7ATxSKsrK0t0WJLv/m0mJfOPikQ1YN60g4SxLLlpK+dFarzojQLVyLrJGWxR cnseiB0IV2PvuV1RRrBntbXWK+rO4Y2PCMt46Hx63NrxwOzffa0s6MjXg3xLMc3p kl0RmoA/lDsIem0iBKF5PysOe7UsjklUO1jgqE53359FQDJDtg5N/BtnpB4wFQh5 NlfJ6q+TG58jYhiiONFN =+qN4 -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
b9600d2d09
|
@ -22,7 +22,8 @@ This file contains
|
|||
4.1.3 RAW socket option CAN_RAW_LOOPBACK
|
||||
4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS
|
||||
4.1.5 RAW socket option CAN_RAW_FD_FRAMES
|
||||
4.1.6 RAW socket returned message flags
|
||||
4.1.6 RAW socket option CAN_RAW_JOIN_FILTERS
|
||||
4.1.7 RAW socket returned message flags
|
||||
4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
|
||||
4.2.1 Broadcast Manager operations
|
||||
4.2.2 Broadcast Manager message flags
|
||||
|
@ -601,7 +602,22 @@ solution for a couple of reasons:
|
|||
CAN FD frames by checking if the device maximum transfer unit is CANFD_MTU.
|
||||
The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall.
|
||||
|
||||
4.1.6 RAW socket returned message flags
|
||||
4.1.6 RAW socket option CAN_RAW_JOIN_FILTERS
|
||||
|
||||
The CAN_RAW socket can set multiple CAN identifier specific filters that
|
||||
lead to multiple filters in the af_can.c filter processing. These filters
|
||||
are indenpendent from each other which leads to logical OR'ed filters when
|
||||
applied (see 4.1.1).
|
||||
|
||||
This socket option joines the given CAN filters in the way that only CAN
|
||||
frames are passed to user space that matched *all* given CAN filters. The
|
||||
semantic for the applied filters is therefore changed to a logical AND.
|
||||
|
||||
This is useful especially when the filterset is a combination of filters
|
||||
where the CAN_INV_FILTER flag is set in order to notch single CAN IDs or
|
||||
CAN ID ranges from the incoming traffic.
|
||||
|
||||
4.1.7 RAW socket returned message flags
|
||||
|
||||
When using recvmsg() call, the msg->msg_flags may contain following flags:
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ MODULE_LICENSE("GPL v2");
|
|||
* CPC_MSG_TYPE_EXT_CAN_FRAME or CPC_MSG_TYPE_EXT_RTR_FRAME.
|
||||
*/
|
||||
struct cpc_can_msg {
|
||||
u32 id;
|
||||
__le32 id;
|
||||
u8 length;
|
||||
u8 msg[8];
|
||||
};
|
||||
|
@ -200,8 +200,8 @@ struct __packed ems_cpc_msg {
|
|||
u8 type; /* type of message */
|
||||
u8 length; /* length of data within union 'msg' */
|
||||
u8 msgid; /* confirmation handle */
|
||||
u32 ts_sec; /* timestamp in seconds */
|
||||
u32 ts_nsec; /* timestamp in nano seconds */
|
||||
__le32 ts_sec; /* timestamp in seconds */
|
||||
__le32 ts_nsec; /* timestamp in nano seconds */
|
||||
|
||||
union {
|
||||
u8 generic[64];
|
||||
|
@ -765,7 +765,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
|
|||
|
||||
msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE];
|
||||
|
||||
msg->msg.can_msg.id = cf->can_id & CAN_ERR_MASK;
|
||||
msg->msg.can_msg.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
|
||||
msg->msg.can_msg.length = cf->can_dlc;
|
||||
|
||||
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
|
|||
msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc;
|
||||
}
|
||||
|
||||
/* Respect byte order */
|
||||
msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id);
|
||||
|
||||
for (i = 0; i < MAX_TX_URBS; i++) {
|
||||
if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) {
|
||||
context = &dev->tx_contexts[i];
|
||||
|
|
|
@ -182,7 +182,7 @@ static inline void *pcan_usb_fd_cmd_buffer(struct peak_usb_device *dev)
|
|||
static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
|
||||
{
|
||||
void *cmd_head = pcan_usb_fd_cmd_buffer(dev);
|
||||
int err;
|
||||
int err = 0;
|
||||
u8 *packet_ptr;
|
||||
int i, n = 1, packet_len;
|
||||
ptrdiff_t cmd_len;
|
||||
|
|
|
@ -57,6 +57,7 @@ enum {
|
|||
CAN_RAW_LOOPBACK, /* local loopback (default:on) */
|
||||
CAN_RAW_RECV_OWN_MSGS, /* receive my own msgs (default:off) */
|
||||
CAN_RAW_FD_FRAMES, /* allow CAN FD frames (default:off) */
|
||||
CAN_RAW_JOIN_FILTERS, /* all filters must match to trigger */
|
||||
};
|
||||
|
||||
#endif /* !_UAPI_CAN_RAW_H */
|
||||
|
|
|
@ -74,6 +74,12 @@ MODULE_ALIAS("can-proto-1");
|
|||
* storing the single filter in dfilter, to avoid using dynamic memory.
|
||||
*/
|
||||
|
||||
struct uniqframe {
|
||||
ktime_t tstamp;
|
||||
const struct sk_buff *skb;
|
||||
unsigned int join_rx_count;
|
||||
};
|
||||
|
||||
struct raw_sock {
|
||||
struct sock sk;
|
||||
int bound;
|
||||
|
@ -82,10 +88,12 @@ struct raw_sock {
|
|||
int loopback;
|
||||
int recv_own_msgs;
|
||||
int fd_frames;
|
||||
int join_filters;
|
||||
int count; /* number of active filters */
|
||||
struct can_filter dfilter; /* default/single filter */
|
||||
struct can_filter *filter; /* pointer to filter(s) */
|
||||
can_err_mask_t err_mask;
|
||||
struct uniqframe __percpu *uniq;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -123,6 +131,26 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
|
|||
if (!ro->fd_frames && oskb->len != CAN_MTU)
|
||||
return;
|
||||
|
||||
/* eliminate multiple filter matches for the same skb */
|
||||
if (this_cpu_ptr(ro->uniq)->skb == oskb &&
|
||||
ktime_equal(this_cpu_ptr(ro->uniq)->tstamp, oskb->tstamp)) {
|
||||
if (ro->join_filters) {
|
||||
this_cpu_inc(ro->uniq->join_rx_count);
|
||||
/* drop frame until all enabled filters matched */
|
||||
if (this_cpu_ptr(ro->uniq)->join_rx_count < ro->count)
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this_cpu_ptr(ro->uniq)->skb = oskb;
|
||||
this_cpu_ptr(ro->uniq)->tstamp = oskb->tstamp;
|
||||
this_cpu_ptr(ro->uniq)->join_rx_count = 1;
|
||||
/* drop first frame to check all enabled filters? */
|
||||
if (ro->join_filters && ro->count > 1)
|
||||
return;
|
||||
}
|
||||
|
||||
/* clone the given skb to be able to enqueue it into the rcv queue */
|
||||
skb = skb_clone(oskb, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
|
@ -296,6 +324,12 @@ static int raw_init(struct sock *sk)
|
|||
ro->loopback = 1;
|
||||
ro->recv_own_msgs = 0;
|
||||
ro->fd_frames = 0;
|
||||
ro->join_filters = 0;
|
||||
|
||||
/* alloc_percpu provides zero'ed memory */
|
||||
ro->uniq = alloc_percpu(struct uniqframe);
|
||||
if (unlikely(!ro->uniq))
|
||||
return -ENOMEM;
|
||||
|
||||
/* set notifier */
|
||||
ro->notifier.notifier_call = raw_notifier;
|
||||
|
@ -339,6 +373,7 @@ static int raw_release(struct socket *sock)
|
|||
ro->ifindex = 0;
|
||||
ro->bound = 0;
|
||||
ro->count = 0;
|
||||
free_percpu(ro->uniq);
|
||||
|
||||
sock_orphan(sk);
|
||||
sock->sk = NULL;
|
||||
|
@ -583,6 +618,15 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
|
|||
|
||||
break;
|
||||
|
||||
case CAN_RAW_JOIN_FILTERS:
|
||||
if (optlen != sizeof(ro->join_filters))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&ro->join_filters, optval, optlen))
|
||||
return -EFAULT;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
|
@ -647,6 +691,12 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
|
|||
val = &ro->fd_frames;
|
||||
break;
|
||||
|
||||
case CAN_RAW_JOIN_FILTERS:
|
||||
if (len > sizeof(int))
|
||||
len = sizeof(int);
|
||||
val = &ro->join_filters;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue