]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - patch-series/2.6.22-rc3/04-can-bcm-proto.diff
Cosmetics: Making all multiline comments look equal.
[socketcan-devel.git] / patch-series / 2.6.22-rc3 / 04-can-bcm-proto.diff
1 DESC
2 CAN: Add broadcast manager (bcm) protocol
3 EDESC
4 This patch adds the CAN broadcast manager (bcm) protocol.
5
6 Signed-Off-By: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
7 Signed-Off-By: Urs Thuermann <urs.thuermann@volkswagen.de>
8
9 ---
10  include/linux/can/bcm.h |   65 +
11  net/can/Kconfig         |   28 
12  net/can/Makefile        |    3 
13  net/can/bcm.c           | 1671 ++++++++++++++++++++++++++++++++++++++++++++++++
14  4 files changed, 1767 insertions(+)
15
16 Index: linux-2.6.22-rc2-git3/include/linux/can/bcm.h
17 ===================================================================
18 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
19 +++ linux-2.6.22-rc2-git3/include/linux/can/bcm.h       2007-05-23 12:25:52.%N +0200
20 @@ -0,0 +1,65 @@
21 +/*
22 + * linux/can/bcm.h
23 + *
24 + * Definitions for CAN Broadcast Manager (BCM)
25 + *
26 + * Author: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
27 + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
28 + * All rights reserved.
29 + *
30 + * Send feedback to <socketcan-users@lists.berlios.de>
31 + *
32 + */
33 +
34 +#ifndef CAN_BCM_H
35 +#define CAN_BCM_H
36 +
37 +/**
38 + * struct bcm_msg_head - head of messages to/from the broadcast manager
39 + * @opcode:    opcode, see enum below.
40 + * @flags:     special flags, see below.
41 + * @count:     number of frames to send before changing interval.
42 + * @ival1:     interval for the first @count frames.
43 + * @ival2:     interval for the following frames.
44 + * @can_id:    CAN ID of frames to be sent or received.
45 + * @nframes:   number of frames appended to the message head.
46 + * @frames:    array of CAN frames.
47 + */
48 +struct bcm_msg_head {
49 +       int opcode;
50 +       int flags;
51 +       int count;
52 +       struct timeval ival1, ival2;
53 +       canid_t can_id;
54 +       int nframes;
55 +       struct can_frame frames[0];
56 +};
57 +
58 +enum {
59 +       TX_SETUP = 1,   /* create (cyclic) transmission task */
60 +       TX_DELETE,      /* remove (cyclic) transmission task */
61 +       TX_READ,        /* read properties of (cyclic) transmission task */
62 +       TX_SEND,        /* send one CAN frame */
63 +       RX_SETUP,       /* create RX content filter subscription */
64 +       RX_DELETE,      /* remove RX content filter subscription */
65 +       RX_READ,        /* read properties of RX content filter subscription */
66 +       TX_STATUS,      /* reply to TX_READ request */
67 +       TX_EXPIRED,     /* notification on performed transmissions (count=0) */
68 +       RX_STATUS,      /* reply to RX_READ request */
69 +       RX_TIMEOUT,     /* cyclic message is absent */
70 +       RX_CHANGED      /* updated CAN frame (detected content change) */
71 +};
72 +
73 +#define SETTIMER            0x0001
74 +#define STARTTIMER          0x0002
75 +#define TX_COUNTEVT         0x0004
76 +#define TX_ANNOUNCE         0x0008
77 +#define TX_CP_CAN_ID        0x0010
78 +#define RX_FILTER_ID        0x0020
79 +#define RX_CHECK_DLC        0x0040
80 +#define RX_NO_AUTOTIMER     0x0080
81 +#define RX_ANNOUNCE_RESUME  0x0100
82 +#define TX_RESET_MULTI_IDX  0x0200
83 +#define RX_RTR_FRAME        0x0400
84 +
85 +#endif /* CAN_BCM_H */
86 Index: linux-2.6.22-rc2-git3/net/can/Kconfig
87 ===================================================================
88 --- linux-2.6.22-rc2-git3.orig/net/can/Kconfig  2007-05-23 12:25:52.%N +0200
89 +++ linux-2.6.22-rc2-git3/net/can/Kconfig       2007-05-23 12:25:52.%N +0200
90 @@ -42,6 +42,34 @@
91           Say Y here if you want non-root users to be able to access CAN_RAW
92           sockets.
93  
94 +config CAN_BCM
95 +       tristate "Broadcast Manager CAN Protocol (with content filtering)"
96 +       depends on CAN
97 +       default N
98 +       ---help---
99 +         The Broadcast Manager offers content filtering, timeout monitoring,
100 +         sending of RTR-frames and cyclic CAN messages without permanent user
101 +         interaction. The BCM can be 'programmed' via the BSD socket API and
102 +         informs you on demand e.g. only on content updates / timeouts.
103 +         You probably want to use the bcm socket in most cases where cyclic
104 +         CAN messages are used on the bus (e.g. in automotive environments).
105 +         To use the Broadcast Manager, use AF_CAN with protocol CAN_BCM.
106 +
107 +config CAN_BCM_USER
108 +       bool "Allow non-root users to access CAN broadcast manager sockets"
109 +       depends on CAN_BCM
110 +       default N
111 +       ---help---
112 +         The Controller Area Network is a local field bus transmitting only
113 +         broadcast messages without any routing and security concepts.
114 +         In the majority of cases the user application has to deal with
115 +         raw CAN frames. Therefore it might be reasonable NOT to restrict
116 +         the CAN access only to the user root, as known from other networks.
117 +         Since CAN_BCM sockets can only send and receive frames to/from CAN
118 +         interfaces this does not affect security of others networks.
119 +         Say Y here if you want non-root users to be able to access CAN_BCM
120 +         sockets.
121 +
122  config CAN_DEBUG_CORE
123         bool "CAN Core debugging messages"
124         depends on CAN
125 Index: linux-2.6.22-rc2-git3/net/can/Makefile
126 ===================================================================
127 --- linux-2.6.22-rc2-git3.orig/net/can/Makefile 2007-05-23 12:25:52.%N +0200
128 +++ linux-2.6.22-rc2-git3/net/can/Makefile      2007-05-23 12:25:52.%N +0200
129 @@ -7,3 +7,6 @@
130  
131  obj-$(CONFIG_CAN_RAW)  += can-raw.o
132  can-raw-objs           := raw.o
133 +
134 +obj-$(CONFIG_CAN_BCM)  += can-bcm.o
135 +can-bcm-objs           := bcm.o
136 Index: linux-2.6.22-rc2-git3/net/can/bcm.c
137 ===================================================================
138 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
139 +++ linux-2.6.22-rc2-git3/net/can/bcm.c 2007-05-23 12:25:52.%N +0200
140 @@ -0,0 +1,1671 @@
141 +/*
142 + * bcm.c - Broadcast Manager to filter/send (cyclic) CAN content
143 + *
144 + * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
145 + * All rights reserved.
146 + *
147 + * Redistribution and use in source and binary forms, with or without
148 + * modification, are permitted provided that the following conditions
149 + * are met:
150 + * 1. Redistributions of source code must retain the above copyright
151 + *    notice, this list of conditions, the following disclaimer and
152 + *    the referenced file 'COPYING'.
153 + * 2. Redistributions in binary form must reproduce the above copyright
154 + *    notice, this list of conditions and the following disclaimer in the
155 + *    documentation and/or other materials provided with the distribution.
156 + * 3. Neither the name of Volkswagen nor the names of its contributors
157 + *    may be used to endorse or promote products derived from this software
158 + *    without specific prior written permission.
159 + *
160 + * Alternatively, provided that this notice is retained in full, this
161 + * software may be distributed under the terms of the GNU General
162 + * Public License ("GPL") version 2 as distributed in the 'COPYING'
163 + * file from the main directory of the linux kernel source.
164 + *
165 + * The provided data structures and external interfaces from this code
166 + * are not restricted to be used by modules with a GPL compatible license.
167 + *
168 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
169 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
170 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
171 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
172 + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
173 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
174 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
175 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
176 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
177 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
178 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
179 + * DAMAGE.
180 + *
181 + * Send feedback to <socketcan-users@lists.berlios.de>
182 + *
183 + */
184 +
185 +#include <linux/module.h>
186 +#include <linux/init.h>
187 +#include <linux/net.h>
188 +#include <linux/netdevice.h>
189 +#include <linux/proc_fs.h>
190 +#include <linux/poll.h>
191 +#include <linux/can.h>
192 +#include <linux/can/core.h>
193 +#include <linux/can/bcm.h>
194 +#include <net/sock.h>
195 +
196 +/* use of last_frames[index].can_dlc */
197 +#define RX_RECV    0x40 /* received data for this element */
198 +#define RX_THR     0x80 /* element not been sent due to throttle feature */
199 +#define BCM_CAN_DLC_MASK 0x0F /* clean private flags in can_dlc by masking */
200 +
201 +/* get best masking value for can_rx_register() for a given single can_id */
202 +#define REGMASK(id) ((id & CAN_RTR_FLAG) | ((id & CAN_EFF_FLAG) ? \
203 +                       (CAN_EFF_MASK | CAN_EFF_FLAG) : CAN_SFF_MASK))
204 +
205 +#define IDENT "bcm"
206 +#define CAN_BCM_VERSION CAN_VERSION
207 +static __initdata const char banner[] = KERN_INFO
208 +       "can: broadcast manager protocol # rev " CAN_BCM_VERSION "\n";
209 +
210 +MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
211 +MODULE_LICENSE("Dual BSD/GPL");
212 +MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
213 +
214 +#ifdef CONFIG_CAN_DEBUG_CORE
215 +static int debug = 0;
216 +module_param(debug, int, S_IRUGO);
217 +MODULE_PARM_DESC(debug, "debug print mask: 1:debug, 2:frames, 4:skbs");
218 +#endif
219 +
220 +/* easy access to can_frame payload */
221 +static inline u64 GET_U64(const struct can_frame *cp)
222 +{
223 +       return *(u64*)cp->data;
224 +}
225 +
226 +struct bcm_op {
227 +       struct list_head list;
228 +       int ifindex;
229 +       canid_t can_id;
230 +       int flags;
231 +       unsigned long j_ival1, j_ival2, j_lastmsg;
232 +       unsigned long frames_abs, frames_filtered;
233 +       struct timer_list timer, thrtimer;
234 +       struct timeval ival1, ival2;
235 +       struct timeval rx_stamp;
236 +       int rx_ifindex;
237 +       int count;
238 +       int nframes;
239 +       int currframe;
240 +       struct can_frame *frames;
241 +       struct can_frame *last_frames;
242 +       struct can_frame sframe;
243 +       struct can_frame last_sframe;
244 +       struct sock *sk;
245 +};
246 +
247 +struct bcm_opt {
248 +       int bound;
249 +       int ifindex;
250 +       struct list_head rx_ops;
251 +       struct list_head tx_ops;
252 +       unsigned long dropped_usr_msgs;
253 +       struct proc_dir_entry *bcm_proc_read;
254 +       char procname [9]; /* pointer printed in ASCII with \0 */
255 +};
256 +
257 +static struct proc_dir_entry *proc_dir = NULL;
258 +
259 +#ifdef CONFIG_CAN_BCM_USER
260 +#define BCM_CAP (-1)
261 +#else
262 +#define BCM_CAP CAP_NET_RAW
263 +#endif
264 +
265 +struct bcm_sock {
266 +       struct sock    sk;
267 +       struct bcm_opt opt;
268 +};
269 +
270 +static inline struct bcm_opt *bcm_sk(const struct sock *sk)
271 +{
272 +       return &((struct bcm_sock *)sk)->opt;
273 +}
274 +
275 +#define CFSIZ sizeof(struct can_frame)
276 +#define OPSIZ sizeof(struct bcm_op)
277 +#define MHSIZ sizeof(struct bcm_msg_head)
278 +
279 +/*
280 + * rounded_tv2jif - calculate jiffies from timeval including optional up
281 + * @tv: pointer to timeval
282 + *
283 + * Description:
284 + * In opposite to timeval_to_jiffies() provided in include/linux/jiffies.h this
285 + * function is intentionally more relaxed on precise timer ticks to get exact
286 + * one jiffy for requested 1000us on a 1000HZ machine.
287 + * This code is to be removed when upgrading to kernel hrtimer.
288 + *
289 + * Return:
290 + *  calculated jiffies (max: ULONG_MAX)
291 + */
292 +static unsigned long rounded_tv2jif(const struct timeval *tv)
293 +{
294 +       unsigned long sec  = tv->tv_sec;
295 +       unsigned long usec = tv->tv_usec;
296 +       unsigned long jif;
297 +
298 +       if (sec > ULONG_MAX / HZ)
299 +               return ULONG_MAX;
300 +
301 +       /* round up to get at least the requested time */
302 +       usec += 1000000 / HZ - 1;
303 +
304 +       jif  = usec / (1000000 / HZ);
305 +
306 +       if (sec * HZ > ULONG_MAX - jif)
307 +               return ULONG_MAX;
308 +
309 +       return jif + sec * HZ;
310 +}
311 +
312 +/*
313 + * procfs functions
314 + */
315 +static char *bcm_proc_getifname(int ifindex)
316 +{
317 +       struct net_device *dev;
318 +
319 +       if (!ifindex)
320 +               return "any";
321 +
322 +       dev = __dev_get_by_index(ifindex); /* no usage counting */
323 +       if (dev)
324 +               return dev->name;
325 +
326 +       return "???";
327 +}
328 +
329 +static int bcm_read_proc(char *page, char **start, off_t off,
330 +                        int count, int *eof, void *data)
331 +{
332 +       int len = 0;
333 +       struct sock *sk = (struct sock *)data;
334 +       struct bcm_opt *bo = bcm_sk(sk);
335 +       struct bcm_op *op;
336 +
337 +       len += snprintf(page + len, PAGE_SIZE - len, ">>> socket %p",
338 +                       sk->sk_socket);
339 +       len += snprintf(page + len, PAGE_SIZE - len, " / sk %p", sk);
340 +       len += snprintf(page + len, PAGE_SIZE - len, " / bo %p", bo);
341 +       len += snprintf(page + len, PAGE_SIZE - len, " / dropped %lu",
342 +                       bo->dropped_usr_msgs);
343 +       len += snprintf(page + len, PAGE_SIZE - len, " / bound %s",
344 +                       bcm_proc_getifname(bo->ifindex));
345 +       len += snprintf(page + len, PAGE_SIZE - len, " <<<\n");
346 +
347 +       list_for_each_entry(op, &bo->rx_ops, list) {
348 +
349 +               unsigned long reduction;
350 +
351 +               /* print only active entries & prevent division by zero */
352 +               if (!op->frames_abs)
353 +                       continue;
354 +
355 +               len += snprintf(page + len, PAGE_SIZE - len,
356 +                               "rx_op: %03X %-5s ",
357 +                               op->can_id, bcm_proc_getifname(op->ifindex));
358 +               len += snprintf(page + len, PAGE_SIZE - len, "[%d]%c ",
359 +                               op->nframes,
360 +                               (op->flags & RX_CHECK_DLC)?'d':' ');
361 +               if (op->j_ival1)
362 +                       len += snprintf(page + len, PAGE_SIZE - len,
363 +                                       "timeo=%ld ", op->j_ival1);
364 +
365 +               if (op->j_ival2)
366 +                       len += snprintf(page + len, PAGE_SIZE - len,
367 +                                       "thr=%ld ", op->j_ival2);
368 +
369 +               len += snprintf(page + len, PAGE_SIZE - len,
370 +                               "# recv %ld (%ld) => reduction: ",
371 +                               op->frames_filtered, op->frames_abs);
372 +
373 +               reduction = 100 - (op->frames_filtered * 100) / op->frames_abs;
374 +
375 +               len += snprintf(page + len, PAGE_SIZE - len, "%s%ld%%\n",
376 +                               (reduction == 100)?"near ":"", reduction);
377 +
378 +               if (len > PAGE_SIZE - 200) {
379 +                       /* mark output cut off */
380 +                       len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
381 +                       break;
382 +               }
383 +       }
384 +
385 +       list_for_each_entry(op, &bo->tx_ops, list) {
386 +
387 +               len += snprintf(page + len, PAGE_SIZE - len,
388 +                               "tx_op: %03X %s [%d] ",
389 +                               op->can_id, bcm_proc_getifname(op->ifindex),
390 +                               op->nframes);
391 +               if (op->j_ival1)
392 +                       len += snprintf(page + len, PAGE_SIZE - len, "t1=%ld ",
393 +                                       op->j_ival1);
394 +
395 +               if (op->j_ival2)
396 +                       len += snprintf(page + len, PAGE_SIZE - len, "t2=%ld ",
397 +                                       op->j_ival2);
398 +
399 +               len += snprintf(page + len, PAGE_SIZE - len, "# sent %ld\n",
400 +                               op->frames_abs);
401 +
402 +               if (len > PAGE_SIZE - 100) {
403 +                       /* mark output cut off */
404 +                       len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
405 +                       break;
406 +               }
407 +       }
408 +
409 +       len += snprintf(page + len, PAGE_SIZE - len, "\n");
410 +
411 +       *eof = 1;
412 +       return len;
413 +}
414 +
415 +/*
416 + * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface
417 + *              of the given bcm tx op
418 + */
419 +static void bcm_can_tx(struct bcm_op *op)
420 +{
421 +       struct sk_buff *skb;
422 +       struct net_device *dev;
423 +       struct can_frame *cf = &op->frames[op->currframe];
424 +
425 +       DBG_FRAME("BCM: bcm_can_tx: sending frame", cf);
426 +
427 +       /* no target device? => exit */
428 +       if (!op->ifindex)
429 +               return;
430 +
431 +       dev = dev_get_by_index(op->ifindex);
432 +
433 +       if (!dev) {
434 +               /* RFC: should this bcm_op remove itself here? */
435 +               return;
436 +       }
437 +
438 +       skb = alloc_skb(CFSIZ,
439 +                       in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
440 +
441 +       if (!skb)
442 +               goto out;
443 +
444 +       memcpy(skb_put(skb, CFSIZ), cf, CFSIZ);
445 +
446 +       /* send with loopback */
447 +       skb->dev = dev;
448 +       skb->sk = op->sk;
449 +       can_send(skb, 1);
450 +
451 +       /* update statistics */
452 +       op->currframe++;
453 +       op->frames_abs++;
454 +
455 +       /* reached last frame? */
456 +       if (op->currframe >= op->nframes)
457 +               op->currframe = 0;
458 + out:
459 +       dev_put(dev);
460 +}
461 +
462 +/*
463 + * bcm_send_to_user - send a BCM message to the userspace
464 + *                    (consisting of bcm_msg_head + x CAN frames)
465 + */
466 +static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
467 +                            struct can_frame *frames, struct timeval *tv)
468 +{
469 +       struct sk_buff *skb;
470 +       struct can_frame *firstframe;
471 +       struct sock *sk = op->sk;
472 +       int datalen = head->nframes * CFSIZ;
473 +       struct sockaddr_can *addr;
474 +       int err;
475 +
476 +       skb = alloc_skb(sizeof(*head) + datalen,
477 +                       in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
478 +       if (!skb)
479 +               return;
480 +
481 +       memcpy(skb_put(skb, sizeof(*head)), head, sizeof(*head));
482 +
483 +       /* can_frames starting here */
484 +       firstframe = (struct can_frame *) skb->tail;
485 +
486 +       if (tv)
487 +               skb_set_timestamp(skb, tv); /* restore timestamp */
488 +
489 +       addr = (struct sockaddr_can *)skb->cb;
490 +       memset(addr, 0, sizeof(*addr));
491 +       addr->can_family  = AF_CAN;
492 +       /* restore originator for recvfrom() */
493 +       addr->can_ifindex = op->rx_ifindex;
494 +
495 +       if (head->nframes) {
496 +               memcpy(skb_put(skb, datalen), frames, datalen);
497 +
498 +               /*
499 +                * the BCM uses the can_dlc-element of the can_frame
500 +                * structure for internal purposes. This is only
501 +                * relevant for updates that are generated by the
502 +                * BCM, where nframes is 1
503 +                */
504 +               if (head->nframes == 1)
505 +                       firstframe->can_dlc &= BCM_CAN_DLC_MASK;
506 +       }
507 +
508 +       err = sock_queue_rcv_skb(sk, skb);
509 +       if (err < 0) {
510 +               struct bcm_opt *bo = bcm_sk(sk);
511 +
512 +               DBG("sock_queue_rcv_skb failed: %d\n", err);
513 +               kfree_skb(skb);
514 +               /* don't care about overflows in this statistic */
515 +               bo->dropped_usr_msgs++;
516 +       }
517 +}
518 +
519 +/*
520 + * bcm_tx_timeout_handler - performes cyclic CAN frame transmissions
521 + */
522 +static void bcm_tx_timeout_handler(unsigned long data)
523 +{
524 +       struct bcm_op *op = (struct bcm_op*)data;
525 +
526 +       DBG("Called with bcm_op %p\n", op);
527 +
528 +       if (op->j_ival1 && (op->count > 0)) {
529 +
530 +               op->count--;
531 +               if (!op->count && (op->flags & TX_COUNTEVT)) {
532 +                       struct bcm_msg_head msg_head;
533 +
534 +                       /* create notification to user */
535 +                       DBG("sending TX_EXPIRED for can_id %03X\n",
536 +                           op->can_id);
537 +
538 +                       msg_head.opcode  = TX_EXPIRED;
539 +                       msg_head.flags   = op->flags;
540 +                       msg_head.count   = op->count;
541 +                       msg_head.ival1   = op->ival1;
542 +                       msg_head.ival2   = op->ival2;
543 +                       msg_head.can_id  = op->can_id;
544 +                       msg_head.nframes = 0;
545 +
546 +                       bcm_send_to_user(op, &msg_head, NULL, NULL);
547 +               }
548 +       }
549 +
550 +       DBG("count=%d j_ival1=%ld j_ival2=%ld\n",
551 +           op->count, op->j_ival1, op->j_ival2);
552 +
553 +       if (op->j_ival1 && (op->count > 0)) {
554 +
555 +               op->timer.expires = jiffies + op->j_ival1;
556 +               add_timer(&op->timer);
557 +
558 +               DBG("adding timer ival1. func=%p data=%p exp=0x%08X\n",
559 +                   op->timer.function,
560 +                   (char*) op->timer.data,
561 +                   (unsigned int) op->timer.expires);
562 +
563 +               /* send (next) frame */
564 +               bcm_can_tx(op);
565 +
566 +       } else {
567 +               if (op->j_ival2) {
568 +                       op->timer.expires = jiffies + op->j_ival2;
569 +                       add_timer(&op->timer);
570 +
571 +                       DBG("adding timer ival2. func=%p data=%p exp=0x%08X\n",
572 +                           op->timer.function,
573 +                           (char*) op->timer.data,
574 +                           (unsigned int) op->timer.expires);
575 +
576 +                       /* send (next) frame */
577 +                       bcm_can_tx(op);
578 +
579 +               } else
580 +                       DBG("no timer restart\n");
581 +       }
582 +
583 +       return;
584 +}
585 +
586 +/*
587 + * bcm_rx_changed - create a RX_CHANGED notification due to changed content
588 + */
589 +static void bcm_rx_changed(struct bcm_op *op, struct can_frame *data)
590 +{
591 +       struct bcm_msg_head head;
592 +
593 +       op->j_lastmsg = jiffies;
594 +
595 +       /* update statistics */
596 +       op->frames_filtered++;
597 +
598 +       /* prevent statistics overflow */
599 +       if (op->frames_filtered > ULONG_MAX/100)
600 +               op->frames_filtered = op->frames_abs = 0;
601 +
602 +       DBG("setting j_lastmsg to 0x%08X for rx_op %p\n",
603 +           (unsigned int) op->j_lastmsg, op);
604 +       DBG("sending notification\n");
605 +
606 +       head.opcode  = RX_CHANGED;
607 +       head.flags   = op->flags;
608 +       head.count   = op->count;
609 +       head.ival1   = op->ival1;
610 +       head.ival2   = op->ival2;
611 +       head.can_id  = op->can_id;
612 +       head.nframes = 1;
613 +
614 +       bcm_send_to_user(op, &head, data, &op->rx_stamp);
615 +}
616 +
617 +/*
618 + * bcm_rx_update_and_send - process a detected relevant receive content change
619 + *                          1. update the last received data
620 + *                          2. send a notification to the user (if possible)
621 + */
622 +static void bcm_rx_update_and_send(struct bcm_op *op,
623 +                                  struct can_frame *lastdata,
624 +                                  struct can_frame *rxdata)
625 +{
626 +       unsigned long nexttx = op->j_lastmsg + op->j_ival2;
627 +
628 +       memcpy(lastdata, rxdata, CFSIZ);
629 +
630 +       /* mark as used */
631 +       lastdata->can_dlc |= RX_RECV;
632 +
633 +       /* throttle bcm_rx_changed ? */
634 +       if ((op->thrtimer.expires) ||
635 +           ((op->j_ival2) && (nexttx > jiffies))) {
636 +               /* we are already waiting OR we have to start waiting */
637 +
638 +               /* mark as 'throttled' */
639 +               lastdata->can_dlc |= RX_THR;
640 +
641 +               if (!(op->thrtimer.expires)) {
642 +                       /* start the timer only the first time */
643 +                       op->thrtimer.expires = nexttx;
644 +                       add_timer(&op->thrtimer);
645 +
646 +                       DBG("adding thrtimer. func=%p data=%p exp=0x%08X\n",
647 +                           op->thrtimer.function,
648 +                           (char*) op->thrtimer.data,
649 +                           (unsigned int) op->thrtimer.expires);
650 +               }
651 +
652 +       } else {
653 +               /* send RX_CHANGED to the user immediately */
654 +               bcm_rx_changed(op, rxdata);
655 +       }
656 +}
657 +
658 +/*
659 + * bcm_rx_cmp_to_index - (bit)compares the currently received data to formerly
660 + *                       received data stored in op->last_frames[]
661 + */
662 +static void bcm_rx_cmp_to_index(struct bcm_op *op, int index,
663 +                               struct can_frame *rxdata)
664 +{
665 +       /*
666 +        * no one uses the MSBs of can_dlc for comparation,
667 +        * so we use it here to detect the first time of reception
668 +        */
669 +
670 +       if (!(op->last_frames[index].can_dlc & RX_RECV)) {
671 +               /* received data for the first time => send update to user */
672 +               DBG("first time :)\n");
673 +               bcm_rx_update_and_send(op, &op->last_frames[index], rxdata);
674 +               return;
675 +       }
676 +
677 +       /* do a real check in can_frame data section */
678 +
679 +       DBG("op->frames[index].data = 0x%016llx\n",
680 +           GET_U64(&op->frames[index]));
681 +       DBG("op->last_frames[index].data = 0x%016llx\n",
682 +           GET_U64(&op->last_frames[index]));
683 +       DBG("rxdata->data = 0x%016llx\n", GET_U64(rxdata));
684 +
685 +       if ((GET_U64(&op->frames[index]) & GET_U64(rxdata)) !=
686 +           (GET_U64(&op->frames[index]) & GET_U64(&op->last_frames[index]))) {
687 +               DBG("relevant data change :)\n");
688 +               bcm_rx_update_and_send(op, &op->last_frames[index], rxdata);
689 +               return;
690 +       }
691 +
692 +       if (op->flags & RX_CHECK_DLC) {
693 +               /* do a real check in can_frame dlc */
694 +               if (rxdata->can_dlc != (op->last_frames[index].can_dlc &
695 +                                       BCM_CAN_DLC_MASK)) {
696 +                       DBG("dlc change :)\n");
697 +                       bcm_rx_update_and_send(op, &op->last_frames[index],
698 +                                              rxdata);
699 +                       return;
700 +               }
701 +       }
702 +       DBG("no relevant change :(\n");
703 +}
704 +
705 +/*
706 + * bcm_rx_starttimer - enable timeout monitoring for CAN frame receiption
707 + */
708 +static void bcm_rx_starttimer(struct bcm_op *op)
709 +{
710 +       if (op->flags & RX_NO_AUTOTIMER)
711 +               return;
712 +
713 +       if (op->j_ival1) {
714 +               op->timer.expires = jiffies + op->j_ival1;
715 +
716 +               DBG("adding rx timeout timer ival1. func=%p data=%p "
717 +                   "exp=0x%08X\n",
718 +                   op->timer.function,
719 +                   (char*) op->timer.data,
720 +                   (unsigned int) op->timer.expires);
721 +
722 +               add_timer(&op->timer);
723 +       }
724 +}
725 +
726 +/*
727 + * bcm_rx_timeout_handler - when the (cyclic) CAN frame receiption timed out
728 + */
729 +static void bcm_rx_timeout_handler(unsigned long data)
730 +{
731 +       struct bcm_op *op = (struct bcm_op*)data;
732 +       struct bcm_msg_head msg_head;
733 +
734 +       DBG("sending RX_TIMEOUT for can_id %03X. op is %p\n", op->can_id, op);
735 +
736 +       msg_head.opcode  = RX_TIMEOUT;
737 +       msg_head.flags   = op->flags;
738 +       msg_head.count   = op->count;
739 +       msg_head.ival1   = op->ival1;
740 +       msg_head.ival2   = op->ival2;
741 +       msg_head.can_id  = op->can_id;
742 +       msg_head.nframes = 0;
743 +
744 +       bcm_send_to_user(op, &msg_head, NULL, NULL);
745 +
746 +       /* no restart of the timer is done here! */
747 +
748 +       /* if user wants to be informed, when cyclic CAN-Messages come back */
749 +       if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) {
750 +               /* clear received can_frames to indicate 'nothing received' */
751 +               memset(op->last_frames, 0, op->nframes * CFSIZ);
752 +               DBG("RX_ANNOUNCE_RESTART\n");
753 +       }
754 +}
755 +
756 +/*
757 + * bcm_rx_thr_handler - the time for blocked content updates is over now:
758 + *                      Check for throttled data and send it to the userspace
759 + */
760 +static void bcm_rx_thr_handler(unsigned long data)
761 +{
762 +       struct bcm_op *op = (struct bcm_op*)data;
763 +       int i = 0;
764 +
765 +       /* mark disabled / consumed timer */
766 +       op->thrtimer.expires = 0;
767 +
768 +       if (op->nframes > 1) {
769 +               DBG("sending MUX RX_CHANGED for can_id %03X. op is %p\n",
770 +                   op->can_id, op);
771 +               /* for MUX filter we start at index 1 */
772 +               for (i=1; i<op->nframes; i++) {
773 +                       if ((op->last_frames) &&
774 +                           (op->last_frames[i].can_dlc & RX_THR)) {
775 +                               op->last_frames[i].can_dlc &= ~RX_THR;
776 +                               bcm_rx_changed(op, &op->last_frames[i]);
777 +                       }
778 +               }
779 +
780 +       } else {
781 +               DBG("sending simple RX_CHANGED for can_id %03X. op is %p\n",
782 +                   op->can_id, op);
783 +               /* for RX_FILTER_ID and simple filter */
784 +               if (op->last_frames && (op->last_frames[0].can_dlc & RX_THR)) {
785 +                       op->last_frames[0].can_dlc &= ~RX_THR;
786 +                       bcm_rx_changed(op, &op->last_frames[0]);
787 +               }
788 +       }
789 +}
790 +
791 +/*
792 + * bcm_rx_handler - handle a CAN frame receiption
793 + */
794 +static void bcm_rx_handler(struct sk_buff *skb, void *data)
795 +{
796 +       struct bcm_op *op = (struct bcm_op*)data;
797 +       struct can_frame rxframe;
798 +       int i;
799 +
800 +       /* disable timeout */
801 +       del_timer(&op->timer);
802 +
803 +       DBG("Called with bcm_op %p\n", op);
804 +
805 +       if (skb->len == sizeof(rxframe)) {
806 +               memcpy(&rxframe, skb->data, sizeof(rxframe));
807 +               /* save rx timestamp */
808 +               skb_get_timestamp(skb, &op->rx_stamp);
809 +               /* save originator for recvfrom() */
810 +               op->rx_ifindex = skb->dev->ifindex;
811 +               /* update statistics */
812 +               op->frames_abs++;
813 +               kfree_skb(skb);
814 +               DBG("got can_frame with can_id %03X\n", rxframe.can_id);
815 +
816 +       } else {
817 +               DBG("Wrong skb->len = %d\n", skb->len);
818 +               kfree_skb(skb);
819 +               return;
820 +       }
821 +
822 +       DBG_FRAME("BCM: bcm_rx_handler: CAN frame", &rxframe);
823 +
824 +       if (op->can_id != rxframe.can_id) {
825 +               DBG("ERROR! Got wrong can_id %03X! Expected %03X.\n",
826 +                   rxframe.can_id, op->can_id);
827 +               return;
828 +       }
829 +
830 +       if (op->flags & RX_RTR_FRAME) {
831 +               /* send reply for RTR-request */
832 +               DBG("RTR-request\n");
833 +
834 +               /* send op->frames[0] to CAN device */
835 +               bcm_can_tx(op);
836 +               return;
837 +       }
838 +
839 +       if (op->flags & RX_FILTER_ID) {
840 +               /* the easiest case */
841 +               DBG("Easy does it with RX_FILTER_ID\n");
842 +
843 +               bcm_rx_update_and_send(op, &op->last_frames[0], &rxframe);
844 +               bcm_rx_starttimer(op);
845 +               return;
846 +       }
847 +
848 +       if (op->nframes == 1) {
849 +               /* simple compare with index 0 */
850 +               DBG("Simple compare\n");
851 +
852 +               bcm_rx_cmp_to_index(op, 0, &rxframe);
853 +               bcm_rx_starttimer(op);
854 +               return;
855 +       }
856 +
857 +       if (op->nframes > 1) {
858 +               /* multiplex compare */
859 +               DBG("Multiplex compare\n");
860 +
861 +               /*
862 +                * find the first multiplex mask that fits.
863 +                * Remark: The MUX-mask is stored in index 0
864 +                */
865 +
866 +               for (i=1; i < op->nframes; i++) {
867 +                       if ((GET_U64(&op->frames[0]) & GET_U64(&rxframe)) ==
868 +                           (GET_U64(&op->frames[0]) &
869 +                            GET_U64(&op->frames[i]))) {
870 +                               DBG("found MUX index %d\n", i);
871 +                               bcm_rx_cmp_to_index(op, i, &rxframe);
872 +                               break;
873 +                       }
874 +               }
875 +               bcm_rx_starttimer(op);
876 +       }
877 +}
878 +
879 +/*
880 + * helpers for bcm_op handling: find & delete bcm [rx|tx] op elements
881 + */
882 +static struct bcm_op *bcm_find_op(struct list_head *ops, canid_t can_id,
883 +                                 int ifindex)
884 +{
885 +       struct bcm_op *op;
886 +
887 +       list_for_each_entry(op, ops, list) {
888 +               if ((op->can_id == can_id) && (op->ifindex == ifindex))
889 +                       return op;
890 +       }
891 +
892 +       return NULL;
893 +}
894 +
895 +static void bcm_remove_op(struct bcm_op *op)
896 +{
897 +       del_timer(&op->timer);
898 +       del_timer(&op->thrtimer);
899 +
900 +       if ((op->frames) && (op->frames != &op->sframe))
901 +               kfree(op->frames);
902 +
903 +       if ((op->last_frames) && (op->last_frames != &op->last_sframe))
904 +               kfree(op->last_frames);
905 +
906 +       kfree(op);
907 +
908 +       return;
909 +}
910 +
911 +/*
912 + * bcm_delete_rx_op - find and remove a rx op (returns number of removed ops)
913 + */
914 +static int bcm_delete_rx_op(struct list_head *ops, canid_t can_id, int ifindex)
915 +{
916 +       struct bcm_op *op, *n;
917 +
918 +       list_for_each_entry_safe(op, n, ops, list) {
919 +               if ((op->can_id == can_id) && (op->ifindex == ifindex)) {
920 +                       DBG("removing rx_op %p for can_id %03X\n",
921 +                           op, op->can_id);
922 +
923 +                       /*
924 +                        * Don't care if we're bound or not (due to netdev
925 +                        * problems) can_rx_unregister() is always a save
926 +                        * thing to do here.
927 +                        */
928 +                       if (op->ifindex) {
929 +                               struct net_device *dev =
930 +                                       dev_get_by_index(op->ifindex);
931 +
932 +                               if (dev) {
933 +                                       can_rx_unregister(dev, op->can_id,
934 +                                                         REGMASK(op->can_id),
935 +                                                         bcm_rx_handler, op);
936 +                                       dev_put(dev);
937 +                               }
938 +
939 +                       } else
940 +                               can_rx_unregister(NULL, op->can_id,
941 +                                                 REGMASK(op->can_id),
942 +                                                 bcm_rx_handler, op);
943 +
944 +                       list_del(&op->list);
945 +                       bcm_remove_op(op);
946 +                       return 1; /* done */
947 +               }
948 +       }
949 +
950 +       return 0; /* not found */
951 +}
952 +
953 +/*
954 + * bcm_delete_tx_op - find and remove a tx op (returns number of removed ops)
955 + */
956 +static int bcm_delete_tx_op(struct list_head *ops, canid_t can_id, int ifindex)
957 +{
958 +       struct bcm_op *op, *n;
959 +
960 +       list_for_each_entry_safe(op, n, ops, list) {
961 +               if ((op->can_id == can_id) && (op->ifindex == ifindex)) {
962 +                       DBG("removing rx_op %p for can_id %03X\n",
963 +                           op, op->can_id);
964 +                       list_del(&op->list);
965 +                       bcm_remove_op(op);
966 +                       return 1; /* done */
967 +               }
968 +       }
969 +
970 +       return 0; /* not found */
971 +}
972 +
973 +/*
974 + * bcm_read_op - read out a bcm_op and send it to the user (for bcm_sendmsg)
975 + */
976 +static int bcm_read_op(struct list_head *ops, struct bcm_msg_head *msg_head,
977 +                      int ifindex)
978 +{
979 +       struct bcm_op *op = bcm_find_op(ops, msg_head->can_id, ifindex);
980 +
981 +       if (!op) {
982 +               DBG("TRX_READ: did not find op for can_id %03X\n",
983 +                   msg_head->can_id);
984 +               return -EINVAL;
985 +       }
986 +
987 +       DBG("TRX_READ: sending status for can_id %03X\n",
988 +           msg_head->can_id);
989 +       /* put current values into msg_head */
990 +       msg_head->flags   = op->flags;
991 +       msg_head->count   = op->count;
992 +       msg_head->ival1   = op->ival1;
993 +       msg_head->ival2   = op->ival2;
994 +       msg_head->nframes = op->nframes;
995 +
996 +       bcm_send_to_user(op, msg_head, op->frames, NULL);
997 +
998 +       return MHSIZ;
999 +}
1000 +
1001 +/*
1002 + * bcm_tx_setup - create or update a bcm tx op (for bcm_sendmsg)
1003 + */
1004 +static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
1005 +                       int ifindex, struct sock *sk)
1006 +{
1007 +       struct bcm_opt *bo = bcm_sk(sk);
1008 +       struct bcm_op *op;
1009 +       int i, err;
1010 +
1011 +       /* we need a real device to send frames */
1012 +       if (!ifindex)
1013 +               return -ENODEV;
1014 +
1015 +       /* we need at least one can_frame */
1016 +       if (msg_head->nframes < 1)
1017 +               return -EINVAL;
1018 +
1019 +       /* check the given can_id */
1020 +       op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex);
1021 +
1022 +       if (op) {
1023 +               /* update existing BCM operation */
1024 +
1025 +               DBG("TX_SETUP: modifying existing tx_op %p for can_id %03X\n",
1026 +                   op, msg_head->can_id);
1027 +
1028 +               /*
1029 +                * Do we need more space for the can_frames than currently
1030 +                * allocated? -> This is a _really_ unusual use-case and
1031 +                * therefore (complexity / locking) it is not supported.
1032 +                */
1033 +               if (msg_head->nframes > op->nframes)
1034 +                       return -E2BIG;
1035 +
1036 +               /* update can_frames content */
1037 +               for (i = 0; i < msg_head->nframes; i++) {
1038 +                       err = memcpy_fromiovec((u8*)&op->frames[i],
1039 +                                              msg->msg_iov, CFSIZ);
1040 +                       if (err < 0)
1041 +                               return err;
1042 +
1043 +                       if (msg_head->flags & TX_CP_CAN_ID) {
1044 +                               /* copy can_id into frame */
1045 +                               op->frames[i].can_id = msg_head->can_id;
1046 +                       }
1047 +               }
1048 +
1049 +       } else {
1050 +               /* insert new BCM operation for the given can_id */
1051 +
1052 +               op = kzalloc(OPSIZ, GFP_KERNEL);
1053 +               if (!op)
1054 +                       return -ENOMEM;
1055 +
1056 +               DBG("TX_SETUP: creating new tx_op %p for can_id %03X\n",
1057 +                   op, msg_head->can_id);
1058 +
1059 +               op->can_id    = msg_head->can_id;
1060 +
1061 +               /* create array for can_frames and copy the data */
1062 +               if (msg_head->nframes > 1) {
1063 +                       op->frames = kmalloc(msg_head->nframes * CFSIZ,
1064 +                                            GFP_KERNEL);
1065 +                       if (!op->frames) {
1066 +                               kfree(op);
1067 +                               return -ENOMEM;
1068 +                       }
1069 +               } else
1070 +                       op->frames = &op->sframe;
1071 +
1072 +               for (i = 0; i < msg_head->nframes; i++) {
1073 +                       err = memcpy_fromiovec((u8*)&op->frames[i],
1074 +                                              msg->msg_iov, CFSIZ);
1075 +                       if (err < 0) {
1076 +                               if (op->frames != &op->sframe)
1077 +                                       kfree(op->frames);
1078 +                               kfree(op);
1079 +                               return err;
1080 +                       }
1081 +
1082 +                       if (msg_head->flags & TX_CP_CAN_ID) {
1083 +                               /* copy can_id into frame */
1084 +                               op->frames[i].can_id = msg_head->can_id;
1085 +                       }
1086 +               }
1087 +
1088 +               /* tx_ops never compare with previous received messages */
1089 +               op->last_frames = NULL;
1090 +
1091 +               /* bcm_can_tx / bcm_tx_timeout_handler needs this */
1092 +               op->sk = sk;
1093 +
1094 +               op->ifindex = ifindex;
1095 +
1096 +               /* initialize uninitialized (kmalloc) structure */
1097 +               init_timer(&op->timer);
1098 +
1099 +               /* currently unused in tx_ops */
1100 +               init_timer(&op->thrtimer);
1101 +
1102 +               /* handler for tx_ops */
1103 +               op->timer.function = bcm_tx_timeout_handler;
1104 +
1105 +               /* timer.data points to this op-structure */
1106 +               op->timer.data = (unsigned long)op;
1107 +
1108 +               /* add this bcm_op to the list of the tx_ops */
1109 +               list_add(&op->list, &bo->tx_ops);
1110 +
1111 +       } /* if ((op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex))) */
1112 +
1113 +       if (op->nframes != msg_head->nframes) {
1114 +               op->nframes   = msg_head->nframes;
1115 +               /* start multiple frame transmission with index 0 */
1116 +               op->currframe = 0;
1117 +       }
1118 +
1119 +       /* check flags */
1120 +
1121 +       op->flags = msg_head->flags;
1122 +
1123 +       if (op->flags & TX_RESET_MULTI_IDX) {
1124 +               /* start multiple frame transmission with index 0 */
1125 +               op->currframe = 0;
1126 +       }
1127 +
1128 +       if (op->flags & SETTIMER) {
1129 +               /* set timer values */
1130 +
1131 +               op->count = msg_head->count;
1132 +               op->ival1 = msg_head->ival1;
1133 +               op->ival2 = msg_head->ival2;
1134 +               op->j_ival1 = rounded_tv2jif(&msg_head->ival1);
1135 +               op->j_ival2 = rounded_tv2jif(&msg_head->ival2);
1136 +
1137 +               DBG("TX_SETUP: SETTIMER count=%d j_ival1=%ld j_ival2=%ld\n",
1138 +                   op->count, op->j_ival1, op->j_ival2);
1139 +
1140 +               /* disable an active timer due to zero values? */
1141 +               if (!op->j_ival1 && !op->j_ival2) {
1142 +                       del_timer(&op->timer);
1143 +                       DBG("TX_SETUP: SETTIMER disabled timer.\n");
1144 +               }
1145 +       }
1146 +
1147 +       if ((op->flags & STARTTIMER) &&
1148 +           ((op->j_ival1 && op->count) || op->j_ival2)) {
1149 +
1150 +               del_timer(&op->timer);
1151 +
1152 +               /* spec: send can_frame when starting timer */
1153 +               op->flags |= TX_ANNOUNCE;
1154 +
1155 +               if (op->j_ival1 && (op->count > 0)) {
1156 +                       op->timer.expires = jiffies + op->j_ival1;
1157 +                       /* op->count-- is done in bcm_tx_timeout_handler */
1158 +                       DBG("TX_SETUP: adding timer ival1. func=%p data=%p "
1159 +                           "exp=0x%08X\n",
1160 +                           op->timer.function,
1161 +                           (char*) op->timer.data,
1162 +                           (unsigned int) op->timer.expires);
1163 +
1164 +               } else {
1165 +                       op->timer.expires = jiffies + op->j_ival2;
1166 +                       DBG("TX_SETUP: adding timer ival2. func=%p data=%p "
1167 +                           "exp=0x%08X\n",
1168 +                           op->timer.function,
1169 +                           (char*) op->timer.data,
1170 +                           (unsigned int) op->timer.expires);
1171 +               }
1172 +
1173 +               add_timer(&op->timer);
1174 +       }
1175 +
1176 +       if (op->flags & TX_ANNOUNCE)
1177 +               bcm_can_tx(op);
1178 +
1179 +       return msg_head->nframes * CFSIZ + MHSIZ;
1180 +}
1181 +
1182 +/*
1183 + * bcm_rx_setup - create or update a bcm rx op (for bcm_sendmsg)
1184 + */
1185 +static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
1186 +                       int ifindex, struct sock *sk)
1187 +{
1188 +       struct bcm_opt *bo = bcm_sk(sk);
1189 +       struct bcm_op *op;
1190 +       int do_rx_register;
1191 +       int err;
1192 +
1193 +       if ((msg_head->flags & RX_FILTER_ID) || (!(msg_head->nframes))) {
1194 +               /* be robust against wrong usage ... */
1195 +               msg_head->flags |= RX_FILTER_ID;
1196 +               msg_head->nframes = 0; /* ignore trailing garbage */
1197 +       }
1198 +
1199 +       if ((msg_head->flags & RX_RTR_FRAME) &&
1200 +           ((msg_head->nframes != 1) ||
1201 +            (!(msg_head->can_id & CAN_RTR_FLAG)))) {
1202 +
1203 +               DBG("RX_SETUP: bad RX_RTR_FRAME setup!\n");
1204 +               return -EINVAL;
1205 +       }
1206 +
1207 +       /* check the given can_id */
1208 +       op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex);
1209 +       if (op) {
1210 +               /* update existing BCM operation */
1211 +
1212 +               DBG("RX_SETUP: modifying existing rx_op %p for can_id %03X\n",
1213 +                   op, msg_head->can_id);
1214 +
1215 +               /*
1216 +                * Do we need more space for the can_frames than currently
1217 +                * allocated? -> This is a _really_ unusual use-case and
1218 +                * therefore (complexity / locking) it is not supported.
1219 +                */
1220 +               if (msg_head->nframes > op->nframes)
1221 +                       return -E2BIG;
1222 +
1223 +               if (msg_head->nframes) {
1224 +                       /* update can_frames content */
1225 +                       err = memcpy_fromiovec((u8*)op->frames,
1226 +                                              msg->msg_iov,
1227 +                                              msg_head->nframes * CFSIZ);
1228 +                       if (err < 0)
1229 +                               return err;
1230 +
1231 +                       /* clear last_frames to indicate 'nothing received' */
1232 +                       memset(op->last_frames, 0, msg_head->nframes * CFSIZ);
1233 +               }
1234 +
1235 +               op->nframes = msg_head->nframes;
1236 +
1237 +               /* Only an update -> do not call can_rx_register() */
1238 +               do_rx_register = 0;
1239 +
1240 +       } else {
1241 +               /* insert new BCM operation for the given can_id */
1242 +
1243 +               op = kzalloc(OPSIZ, GFP_KERNEL);
1244 +               if (!op)
1245 +                       return -ENOMEM;
1246 +
1247 +               DBG("RX_SETUP: creating new rx_op %p for can_id %03X\n",
1248 +                   op, msg_head->can_id);
1249 +
1250 +               op->can_id    = msg_head->can_id;
1251 +               op->nframes   = msg_head->nframes;
1252 +
1253 +               if (msg_head->nframes > 1) {
1254 +                       /* create array for can_frames and copy the data */
1255 +                       op->frames = kmalloc(msg_head->nframes * CFSIZ,
1256 +                                            GFP_KERNEL);
1257 +                       if (!op->frames) {
1258 +                               kfree(op);
1259 +                               return -ENOMEM;
1260 +                       }
1261 +
1262 +                       /* create and init array for received can_frames */
1263 +                       op->last_frames = kzalloc(msg_head->nframes * CFSIZ,
1264 +                                                 GFP_KERNEL);
1265 +                       if (!op->last_frames) {
1266 +                               kfree(op->frames);
1267 +                               kfree(op);
1268 +                               return -ENOMEM;
1269 +                       }
1270 +
1271 +               } else {
1272 +                       op->frames = &op->sframe;
1273 +                       op->last_frames = &op->last_sframe;
1274 +               }
1275 +
1276 +               if (msg_head->nframes) {
1277 +                       err = memcpy_fromiovec((u8*)op->frames, msg->msg_iov,
1278 +                                              msg_head->nframes * CFSIZ);
1279 +                       if (err < 0) {
1280 +                               if (op->frames != &op->sframe)
1281 +                                       kfree(op->frames);
1282 +                               if (op->last_frames != &op->last_sframe)
1283 +                                       kfree(op->last_frames);
1284 +                               kfree(op);
1285 +                               return err;
1286 +                       }
1287 +               }
1288 +
1289 +               op->sk = sk;
1290 +               op->ifindex = ifindex;
1291 +
1292 +               /* initialize uninitialized (kzalloc) structure */
1293 +               init_timer(&op->timer);
1294 +
1295 +               /* init throttle timer for RX_CHANGED */
1296 +               init_timer(&op->thrtimer);
1297 +
1298 +               /* handler for rx timeouts */
1299 +               op->timer.function = bcm_rx_timeout_handler;
1300 +
1301 +               /* timer.data points to this op-structure */
1302 +               op->timer.data = (unsigned long)op;
1303 +
1304 +               /* handler for RX_CHANGED throttle timeouts */
1305 +               op->thrtimer.function = bcm_rx_thr_handler;
1306 +
1307 +               /* timer.data points to this op-structure */
1308 +               op->thrtimer.data = (unsigned long)op;
1309 +
1310 +               /* mark disabled timer */
1311 +               op->thrtimer.expires = 0;
1312 +
1313 +               /* add this bcm_op to the list of the tx_ops */
1314 +               list_add(&op->list, &bo->rx_ops);
1315 +
1316 +               /* call can_rx_register() */
1317 +               do_rx_register = 1;
1318 +
1319 +       } /* if ((op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex))) */
1320 +
1321 +       /* check flags */
1322 +       op->flags = msg_head->flags;
1323 +
1324 +       if (op->flags & RX_RTR_FRAME) {
1325 +
1326 +               /* no timers in RTR-mode */
1327 +               del_timer(&op->thrtimer);
1328 +               del_timer(&op->timer);
1329 +
1330 +               /*
1331 +                * funny feature in RX(!)_SETUP only for RTR-mode:
1332 +                * copy can_id into frame BUT without RTR-flag to
1333 +                * prevent a full-load-loopback-test ... ;-]
1334 +                */
1335 +               if ((op->flags & TX_CP_CAN_ID) ||
1336 +                   (op->frames[0].can_id == op->can_id))
1337 +                       op->frames[0].can_id = op->can_id & ~CAN_RTR_FLAG;
1338 +
1339 +       } else {
1340 +               if (op->flags & SETTIMER) {
1341 +
1342 +                       /* set timer value */
1343 +                       op->ival1 = msg_head->ival1;
1344 +                       op->ival2 = msg_head->ival2;
1345 +                       op->j_ival1 = rounded_tv2jif(&msg_head->ival1);
1346 +                       op->j_ival2 = rounded_tv2jif(&msg_head->ival2);
1347 +
1348 +                       DBG("RX_SETUP: SETTIMER j_ival1=%ld j_ival2=%ld\n",
1349 +                           op->j_ival1, op->j_ival2);
1350 +
1351 +                       /* disable an active timer due to zero value? */
1352 +                       if (!op->j_ival1) {
1353 +                               del_timer(&op->timer);
1354 +                               DBG("RX_SETUP: disabled timer rx timeouts.\n");
1355 +                       }
1356 +
1357 +                       /* free currently blocked msgs ? */
1358 +                       if (op->thrtimer.expires) {
1359 +                               DBG("RX_SETUP: unblocking throttled msgs.\n");
1360 +                               del_timer(&op->thrtimer);
1361 +                               /* send blocked msgs hereafter */
1362 +                               op->thrtimer.expires = jiffies + 2;
1363 +                               add_timer(&op->thrtimer);
1364 +                       }
1365 +                       /*
1366 +                        * if (op->j_ival2) is zero, no (new) throttling
1367 +                        * will happen. For details see functions
1368 +                        * bcm_rx_update_and_send() and bcm_rx_thr_handler()
1369 +                        */
1370 +               }
1371 +
1372 +               if ((op->flags & STARTTIMER) && op->j_ival1) {
1373 +
1374 +                       del_timer(&op->timer);
1375 +                       op->timer.expires = jiffies + op->j_ival1;
1376 +
1377 +                       DBG("RX_SETUP: adding timer ival1. func=%p data=%p"
1378 +                           " exp=0x%08X\n",
1379 +                           (char *) op->timer.function,
1380 +                           (char *) op->timer.data,
1381 +                           (unsigned int) op->timer.expires);
1382 +
1383 +                       add_timer(&op->timer);
1384 +               }
1385 +       }
1386 +
1387 +       /* now we can register for can_ids, if we added a new bcm_op */
1388 +       if (do_rx_register) {
1389 +               DBG("RX_SETUP: can_rx_register() for can_id %03X. "
1390 +                   "rx_op is %p\n", op->can_id, op);
1391 +
1392 +               if (ifindex) {
1393 +                       struct net_device *dev = dev_get_by_index(ifindex);
1394 +
1395 +                       if (dev) {
1396 +                               can_rx_register(dev, op->can_id,
1397 +                                               REGMASK(op->can_id),
1398 +                                               bcm_rx_handler, op, IDENT);
1399 +                               dev_put(dev);
1400 +                       }
1401 +
1402 +               } else
1403 +                       can_rx_register(NULL, op->can_id, REGMASK(op->can_id),
1404 +                                       bcm_rx_handler, op, IDENT);
1405 +       }
1406 +
1407 +       return msg_head->nframes * CFSIZ + MHSIZ;
1408 +}
1409 +
1410 +/*
1411 + * bcm_tx_send - send a single CAN frame to the CAN interface (for bcm_sendmsg)
1412 + */
1413 +static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
1414 +{
1415 +       struct sk_buff *skb;
1416 +       struct net_device *dev;
1417 +       int err;
1418 +
1419 +       /* just copy and send one can_frame */
1420 +
1421 +       if (!ifindex) /* we need a real device to send frames */
1422 +               return -ENODEV;
1423 +
1424 +       skb = alloc_skb(CFSIZ, GFP_KERNEL);
1425 +
1426 +       if (!skb)
1427 +               return -ENOMEM;
1428 +
1429 +       err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ);
1430 +       if (err < 0) {
1431 +               kfree_skb(skb);
1432 +               return err;
1433 +       }
1434 +
1435 +       DBG_FRAME("BCM: TX_SEND: sending frame",
1436 +                 (struct can_frame *)skb->data);
1437 +
1438 +       dev = dev_get_by_index(ifindex);
1439 +       if (!dev) {
1440 +               kfree_skb(skb);
1441 +               return -ENODEV;
1442 +       }
1443 +
1444 +       skb->dev = dev;
1445 +       skb->sk  = sk;
1446 +       can_send(skb, 1); /* send with loopback */
1447 +       dev_put(dev);
1448 +
1449 +       return CFSIZ + MHSIZ;
1450 +}
1451 +
1452 +/*
1453 + * bcm_sendmsg - process BCM commands (opcodes) from the userspace
1454 + */
1455 +static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
1456 +                      struct msghdr *msg, size_t size)
1457 +{
1458 +       struct sock *sk = sock->sk;
1459 +       struct bcm_opt *bo = bcm_sk(sk);
1460 +       int ifindex = bo->ifindex; /* default ifindex for this bcm_op */
1461 +       struct bcm_msg_head msg_head;
1462 +       int ret; /* read bytes or error codes as return value */
1463 +
1464 +       if (!bo->bound) {
1465 +               DBG("sock %p not bound\n", sk);
1466 +               return -ENOTCONN;
1467 +       }
1468 +
1469 +       /* check for alternative ifindex for this bcm_op */
1470 +
1471 +       if (!ifindex && msg->msg_name) {
1472 +               /* no bound device as default => check msg_name */
1473 +               struct sockaddr_can *addr =
1474 +                       (struct sockaddr_can *)msg->msg_name;
1475 +
1476 +               if (addr->can_family != AF_CAN)
1477 +                       return -EINVAL;
1478 +
1479 +               ifindex = addr->can_ifindex; /* ifindex from sendto() */
1480 +
1481 +               if (ifindex && !dev_get_by_index(ifindex)) {
1482 +                       DBG("device %d not found\n", ifindex);
1483 +                       return -ENODEV;
1484 +               }
1485 +       }
1486 +
1487 +       /* read message head information */
1488 +
1489 +       ret = memcpy_fromiovec((u8*)&msg_head, msg->msg_iov, MHSIZ);
1490 +       if (ret < 0)
1491 +               return ret;
1492 +
1493 +       DBG("opcode %d for can_id %03X\n", msg_head.opcode, msg_head.can_id);
1494 +
1495 +       lock_sock(sk);
1496 +
1497 +       switch (msg_head.opcode) {
1498 +
1499 +       case TX_SETUP:
1500 +               ret = bcm_tx_setup(&msg_head, msg, ifindex, sk);
1501 +               break;
1502 +
1503 +       case RX_SETUP:
1504 +               ret = bcm_rx_setup(&msg_head, msg, ifindex, sk);
1505 +               break;
1506 +
1507 +       case TX_DELETE:
1508 +               if (bcm_delete_tx_op(&bo->tx_ops, msg_head.can_id, ifindex))
1509 +                       ret = MHSIZ;
1510 +               else
1511 +                       ret = -EINVAL;
1512 +               break;
1513 +
1514 +       case RX_DELETE:
1515 +               if (bcm_delete_rx_op(&bo->rx_ops, msg_head.can_id, ifindex))
1516 +                       ret = MHSIZ;
1517 +               else
1518 +                       ret = -EINVAL;
1519 +               break;
1520 +
1521 +       case TX_READ:
1522 +               /* reuse msg_head for the reply to TX_READ */
1523 +               msg_head.opcode  = TX_STATUS;
1524 +               ret = bcm_read_op(&bo->tx_ops, &msg_head, ifindex);
1525 +               break;
1526 +
1527 +       case RX_READ:
1528 +               /* reuse msg_head for the reply to RX_READ */
1529 +               msg_head.opcode  = RX_STATUS;
1530 +               ret = bcm_read_op(&bo->rx_ops, &msg_head, ifindex);
1531 +               break;
1532 +
1533 +       case TX_SEND:
1534 +               /* we need at least one can_frame */
1535 +               if (msg_head.nframes < 1)
1536 +                       ret = -EINVAL;
1537 +               else
1538 +                       ret = bcm_tx_send(msg, ifindex, sk);
1539 +               break;
1540 +
1541 +       default:
1542 +               DBG("Unknown opcode %d\n", msg_head.opcode);
1543 +               ret = -EINVAL;
1544 +               break;
1545 +       }
1546 +
1547 +       release_sock(sk);
1548 +
1549 +       return ret;
1550 +}
1551 +
1552 +/*
1553 + * initial settings for all BCM sockets to be set at socket creation time
1554 + */
1555 +static int bcm_init(struct sock *sk)
1556 +{
1557 +       struct bcm_opt *bo = bcm_sk(sk);
1558 +
1559 +       bo->bound            = 0;
1560 +       bo->ifindex          = 0;
1561 +       bo->dropped_usr_msgs = 0;
1562 +       bo->bcm_proc_read    = NULL;
1563 +
1564 +       INIT_LIST_HEAD(&bo->tx_ops);
1565 +       INIT_LIST_HEAD(&bo->rx_ops);
1566 +
1567 +       return 0;
1568 +}
1569 +
1570 +/*
1571 + * notification handler for netdevice status changes
1572 + */
1573 +static void bcm_notifier(unsigned long msg, void *data)
1574 +{
1575 +       struct sock *sk = (struct sock *)data;
1576 +       struct bcm_opt *bo = bcm_sk(sk);
1577 +
1578 +       DBG("called for sock %p\n", sk);
1579 +
1580 +       switch (msg) {
1581 +
1582 +       case NETDEV_UNREGISTER:
1583 +               bo->bound   = 0;
1584 +               bo->ifindex = 0;
1585 +               /* fallthrough */
1586 +       case NETDEV_DOWN:
1587 +               sk->sk_err = ENETDOWN;
1588 +               if (!sock_flag(sk, SOCK_DEAD))
1589 +                       sk->sk_error_report(sk);
1590 +       }
1591 +}
1592 +
1593 +/*
1594 + * standard socket functions
1595 + */
1596 +static int bcm_release(struct socket *sock)
1597 +{
1598 +       struct sock *sk = sock->sk;
1599 +       struct bcm_opt *bo = bcm_sk(sk);
1600 +       struct bcm_op *op, *next;
1601 +
1602 +       DBG("socket %p, sk %p\n", sock, sk);
1603 +
1604 +       /* remove bcm_ops, timer, rx_unregister(), etc. */
1605 +
1606 +       list_for_each_entry_safe(op, next, &bo->tx_ops, list) {
1607 +               DBG("removing tx_op %p for can_id %03X\n", op, op->can_id);
1608 +               bcm_remove_op(op);
1609 +       }
1610 +
1611 +       list_for_each_entry_safe(op, next, &bo->rx_ops, list) {
1612 +               DBG("removing rx_op %p for can_id %03X\n", op, op->can_id);
1613 +
1614 +               /*
1615 +                * Don't care if we're bound or not (due to netdev problems)
1616 +                * can_rx_unregister() is always a save thing to do here.
1617 +                */
1618 +               if (op->ifindex) {
1619 +                       struct net_device *dev = dev_get_by_index(op->ifindex);
1620 +
1621 +                       if (dev) {
1622 +                               can_rx_unregister(dev, op->can_id,
1623 +                                                 REGMASK(op->can_id),
1624 +                                                 bcm_rx_handler, op);
1625 +                               dev_put(dev);
1626 +                       }
1627 +
1628 +               } else
1629 +                       can_rx_unregister(NULL, op->can_id,
1630 +                                         REGMASK(op->can_id),
1631 +                                         bcm_rx_handler, op);
1632 +
1633 +               bcm_remove_op(op);
1634 +       }
1635 +
1636 +       /* remove procfs entry */
1637 +       if (proc_dir && bo->bcm_proc_read)
1638 +               remove_proc_entry(bo->procname, proc_dir);
1639 +
1640 +       /* remove device notifier */
1641 +       if (bo->ifindex) {
1642 +               struct net_device *dev = dev_get_by_index(bo->ifindex);
1643 +
1644 +               if (dev) {
1645 +                       can_dev_unregister(dev, bcm_notifier, sk);
1646 +                       dev_put(dev);
1647 +               }
1648 +       }
1649 +
1650 +       sock_put(sk);
1651 +
1652 +       return 0;
1653 +}
1654 +
1655 +static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
1656 +                      int flags)
1657 +{
1658 +       struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
1659 +       struct sock *sk = sock->sk;
1660 +       struct bcm_opt *bo = bcm_sk(sk);
1661 +
1662 +       if (bo->bound)
1663 +               return -EISCONN;
1664 +
1665 +       /* bind a device to this socket */
1666 +       if (addr->can_ifindex) {
1667 +               struct net_device *dev = dev_get_by_index(addr->can_ifindex);
1668 +
1669 +               if (!dev) {
1670 +                       DBG("could not find device index %d\n",
1671 +                           addr->can_ifindex);
1672 +                       return -ENODEV;
1673 +               }
1674 +               bo->ifindex = dev->ifindex;
1675 +               can_dev_register(dev, bcm_notifier, sk); /* register notif. */
1676 +               dev_put(dev);
1677 +
1678 +               DBG("socket %p bound to device %s (idx %d)\n",
1679 +                   sock, dev->name, dev->ifindex);
1680 +
1681 +       } else {
1682 +               /* no notifier for ifindex = 0 ('any' CAN device) */
1683 +               bo->ifindex = 0;
1684 +       }
1685 +
1686 +       bo->bound = 1;
1687 +
1688 +       if (proc_dir) {
1689 +               /* unique socket address as filename */
1690 +               sprintf(bo->procname, "%p", sock);
1691 +               bo->bcm_proc_read = create_proc_read_entry(bo->procname, 0644,
1692 +                                                          proc_dir,
1693 +                                                          bcm_read_proc, sk);
1694 +       }
1695 +
1696 +       return 0;
1697 +}
1698 +
1699 +static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
1700 +                      struct msghdr *msg, size_t size, int flags)
1701 +{
1702 +       struct sock *sk = sock->sk;
1703 +       struct sk_buff *skb;
1704 +       int error = 0;
1705 +       int noblock;
1706 +       int err;
1707 +
1708 +       DBG("socket %p, sk %p\n", sock, sk);
1709 +
1710 +       noblock =  flags & MSG_DONTWAIT;
1711 +       flags   &= ~MSG_DONTWAIT;
1712 +       skb = skb_recv_datagram(sk, flags, noblock, &error);
1713 +       if (!skb)
1714 +               return error;
1715 +
1716 +       DBG("delivering skbuff %p\n", skb);
1717 +       DBG_SKB(skb);
1718 +
1719 +       if (skb->len < size)
1720 +               size = skb->len;
1721 +
1722 +       err = memcpy_toiovec(msg->msg_iov, skb->data, size);
1723 +       if (err < 0) {
1724 +               skb_free_datagram(sk, skb);
1725 +               return err;
1726 +       }
1727 +
1728 +       sock_recv_timestamp(msg, sk, skb);
1729 +
1730 +       if (msg->msg_name) {
1731 +               msg->msg_namelen = sizeof(struct sockaddr_can);
1732 +               memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
1733 +       }
1734 +
1735 +       DBG("freeing sock %p, skbuff %p\n", sk, skb);
1736 +       skb_free_datagram(sk, skb);
1737 +
1738 +       return size;
1739 +}
1740 +
1741 +static unsigned int bcm_poll(struct file *file, struct socket *sock,
1742 +                            poll_table *wait)
1743 +{
1744 +       unsigned int mask = 0;
1745 +
1746 +       DBG("socket %p\n", sock);
1747 +
1748 +       mask = datagram_poll(file, sock, wait);
1749 +       return mask;
1750 +}
1751 +
1752 +static struct proto_ops bcm_ops = {
1753 +       .family        = PF_CAN,
1754 +       .release       = bcm_release,
1755 +       .bind          = sock_no_bind,
1756 +       .connect       = bcm_connect,
1757 +       .socketpair    = sock_no_socketpair,
1758 +       .accept        = sock_no_accept,
1759 +       .getname       = sock_no_getname,
1760 +       .poll          = bcm_poll,
1761 +       .ioctl         = NULL,          /* use can_ioctl() from af_can.c */
1762 +       .listen        = sock_no_listen,
1763 +       .shutdown      = sock_no_shutdown,
1764 +       .setsockopt    = sock_no_setsockopt,
1765 +       .getsockopt    = sock_no_getsockopt,
1766 +       .sendmsg       = bcm_sendmsg,
1767 +       .recvmsg       = bcm_recvmsg,
1768 +       .mmap          = sock_no_mmap,
1769 +       .sendpage      = sock_no_sendpage,
1770 +};
1771 +
1772 +static struct proto bcm_proto = {
1773 +       .name       = "CAN_BCM",
1774 +       .owner      = THIS_MODULE,
1775 +       .obj_size   = sizeof(struct bcm_sock),
1776 +       .init       = bcm_init,
1777 +};
1778 +
1779 +static struct can_proto bcm_can_proto = {
1780 +       .type       = SOCK_DGRAM,
1781 +       .protocol   = CAN_BCM,
1782 +       .capability = BCM_CAP,
1783 +       .ops        = &bcm_ops,
1784 +       .prot       = &bcm_proto,
1785 +};
1786 +
1787 +static int __init bcm_module_init(void)
1788 +{
1789 +       printk(banner);
1790 +
1791 +       can_proto_register(&bcm_can_proto);
1792 +
1793 +       /* create /proc/net/can/bcm directory */
1794 +       proc_dir = proc_mkdir(CAN_PROC_DIR"/"IDENT, NULL);
1795 +
1796 +       if (proc_dir)
1797 +               proc_dir->owner = THIS_MODULE;
1798 +
1799 +       return 0;
1800 +}
1801 +
1802 +static void __exit bcm_module_exit(void)
1803 +{
1804 +       can_proto_unregister(&bcm_can_proto);
1805 +
1806 +       if (proc_dir)
1807 +               remove_proc_entry(CAN_PROC_DIR"/"IDENT, NULL);
1808 +}
1809 +
1810 +module_init(bcm_module_init);
1811 +module_exit(bcm_module_exit);