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