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