Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[CAN]: Add broadcast manager (bcm) protocol

This patch adds the CAN broadcast manager (bcm) protocol.

Signed-off-by: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
Signed-off-by: Urs Thuermann <urs.thuermann@volkswagen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Oliver Hartkopp and committed by
David S. Miller
ffd980f9 c18ce101

+1642
+65
include/linux/can/bcm.h
··· 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 + */ 28 + struct 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 + 38 + enum { 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 */
+13
net/can/Kconfig
··· 26 26 most cases where no higher level protocol is being used. The raw 27 27 socket has several filter options e.g. ID masking / error frames. 28 28 To receive/send raw CAN messages, use AF_CAN with protocol CAN_RAW. 29 + 30 + config 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.
+3
net/can/Makefile
··· 7 7 8 8 obj-$(CONFIG_CAN_RAW) += can-raw.o 9 9 can-raw-objs := raw.o 10 + 11 + obj-$(CONFIG_CAN_BCM) += can-bcm.o 12 + can-bcm-objs := bcm.o
+1561
net/can/bcm.c
··· 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 70 + static __initdata const char banner[] = KERN_INFO 71 + "can: broadcast manager protocol (rev " CAN_BCM_VERSION ")\n"; 72 + 73 + MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); 74 + MODULE_LICENSE("Dual BSD/GPL"); 75 + MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>"); 76 + 77 + /* easy access to can_frame payload */ 78 + static inline u64 GET_U64(const struct can_frame *cp) 79 + { 80 + return *(u64 *)cp->data; 81 + } 82 + 83 + struct 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 + 105 + static struct proc_dir_entry *proc_dir; 106 + 107 + struct 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 + 119 + static 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 + */ 141 + static 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 + */ 164 + static 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 + 179 + static 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 + */ 269 + static 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 + */ 311 + static 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 + */ 374 + static 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 + */ 418 + static 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 + */ 447 + static 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 + */ 481 + static 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 + */ 517 + static 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 + */ 529 + static 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 + */ 557 + static 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 + */ 587 + static 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 + */ 657 + static 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 + 670 + static 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 + 686 + static 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 + */ 702 + static 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 + */ 747 + static 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 + */ 765 + static 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 + */ 788 + static 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 + */ 935 + static 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 + */ 1135 + static 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 + */ 1173 + static 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 + */ 1279 + static 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 + */ 1334 + static 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 + */ 1357 + static 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 + 1416 + static 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 + 1460 + static 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 + 1496 + static 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 + 1516 + static 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 + 1523 + static 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 + 1531 + static 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 + 1552 + static 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 + 1560 + module_init(bcm_module_init); 1561 + module_exit(bcm_module_exit);