Lines Matching +full:inverted +full:- +full:rx

1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 /* af_can.c - Protocol family CAN core module
5 * Copyright (c) 2002-2017 Volkswagen Group Electronic Research
61 #include <linux/can/can-ml.h>
91 skb_queue_purge(&sk->sk_receive_queue); in can_sock_destruct()
92 skb_queue_purge(&sk->sk_error_queue); in can_sock_destruct()
102 if (cp && !try_module_get(cp->prot->owner)) in can_get_proto()
111 module_put(cp->prot->owner); in can_put_proto()
121 sock->state = SS_UNCONNECTED; in can_create()
124 return -EINVAL; in can_create()
132 err = request_module("can-proto-%d", protocol); in can_create()
136 * return -EPROTONOSUPPORT in can_create()
139 pr_err_ratelimited("can: request_module (can-proto-%d) failed.\n", in can_create()
149 return -EPROTONOSUPPORT; in can_create()
151 if (cp->type != sock->type) { in can_create()
152 err = -EPROTOTYPE; in can_create()
156 sock->ops = cp->ops; in can_create()
158 sk = sk_alloc(net, PF_CAN, GFP_KERNEL, cp->prot, kern); in can_create()
160 err = -ENOMEM; in can_create()
165 sk->sk_destruct = can_sock_destruct; in can_create()
167 if (sk->sk_prot->init) in can_create()
168 err = sk->sk_prot->init(sk); in can_create()
174 sock->sk = NULL; in can_create()
176 sock_prot_inuse_add(net, sk->sk_prot, 1); in can_create()
187 * can_send - transmit a CAN frame (optional with local loopback)
195 * -ENETDOWN when the selected interface is down
196 * -ENOBUFS on full driver queue (see net_xmit_errno())
197 * -ENOMEM when local loopback failed at calling skb_clone()
198 * -EPERM when trying to send on a non-CAN interface
199 * -EMSGSIZE CAN frame size is bigger than CAN interface MTU
200 * -EINVAL when the skb->data does not contain a valid CAN frame
205 struct can_pkg_stats *pkg_stats = dev_net(skb->dev)->can.pkg_stats; in can_send()
206 int err = -EINVAL; in can_send()
209 skb->protocol = htons(ETH_P_CANXL); in can_send()
211 skb->protocol = htons(ETH_P_CAN); in can_send()
213 struct canfd_frame *cfd = (struct canfd_frame *)skb->data; in can_send()
215 skb->protocol = htons(ETH_P_CANFD); in can_send()
218 cfd->flags |= CANFD_FDF; in can_send()
224 if (unlikely(skb->len > skb->dev->mtu)) { in can_send()
225 err = -EMSGSIZE; in can_send()
229 if (unlikely(skb->dev->type != ARPHRD_CAN)) { in can_send()
230 err = -EPERM; in can_send()
234 if (unlikely(!(skb->dev->flags & IFF_UP))) { in can_send()
235 err = -ENETDOWN; in can_send()
239 skb->ip_summed = CHECKSUM_UNNECESSARY; in can_send()
249 skb->pkt_type = PACKET_LOOPBACK; in can_send()
254 * Therefore we have to ensure that skb->sk remains the in can_send()
255 * reference to the originating sock by restoring skb->sk in can_send()
259 if (!(skb->dev->flags & IFF_ECHO)) { in can_send()
266 return -ENOMEM; in can_send()
269 can_skb_set_owner(newskb, skb->sk); in can_send()
270 newskb->ip_summed = CHECKSUM_UNNECESSARY; in can_send()
271 newskb->pkt_type = PACKET_BROADCAST; in can_send()
275 skb->pkt_type = PACKET_HOST; in can_send()
292 atomic_long_inc(&pkg_stats->tx_frames); in can_send()
293 atomic_long_inc(&pkg_stats->tx_frames_delta); in can_send()
303 /* af_can rx path */
310 return &can_ml->dev_rcv_lists; in can_dev_rcv_lists_find()
312 return net->can.rx_alldev_list; in can_dev_rcv_lists_find()
317 * effhash - hash function for 29 bit CAN identifier reduction
326 * Hash value from 0x000 - 0x3FF ( enforced by CAN_EFF_RCV_HASH_BITS mask )
336 return hash & ((1 << CAN_EFF_RCV_HASH_BITS) - 1); in effhash()
340 * can_rcv_list_find - determine optimal filterlist inside device filter struct
357 * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
359 * frames there is a special filterlist and a special rx path filter handling.
375 return &dev_rcv_lists->rx[RX_ERR]; in can_rcv_list_find()
391 return &dev_rcv_lists->rx[RX_INV]; in can_rcv_list_find()
395 return &dev_rcv_lists->rx[RX_ALL]; in can_rcv_list_find()
397 /* extra filterlists for the subscription of a single non-RTR can_id */ in can_rcv_list_find()
402 return &dev_rcv_lists->rx_eff[effhash(*can_id)]; in can_rcv_list_find()
405 return &dev_rcv_lists->rx_sff[*can_id]; in can_rcv_list_find()
410 return &dev_rcv_lists->rx[RX_FIL]; in can_rcv_list_find()
414 * can_rx_register - subscribe CAN frames from a specific interface
430 * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
441 * -ENOMEM on missing cache mem to create subscription entry
442 * -ENODEV unknown device
451 struct can_rcv_lists_stats *rcv_lists_stats = net->can.rcv_lists_stats; in can_rx_register()
453 /* insert new receiver (dev,canid,mask) -> (func,data) */ in can_rx_register()
455 if (dev && (dev->type != ARPHRD_CAN || !can_get_ml_priv(dev))) in can_rx_register()
456 return -ENODEV; in can_rx_register()
459 return -ENODEV; in can_rx_register()
463 return -ENOMEM; in can_rx_register()
465 spin_lock_bh(&net->can.rcvlists_lock); in can_rx_register()
470 rcv->can_id = can_id; in can_rx_register()
471 rcv->mask = mask; in can_rx_register()
472 rcv->matches = 0; in can_rx_register()
473 rcv->func = func; in can_rx_register()
474 rcv->data = data; in can_rx_register()
475 rcv->ident = ident; in can_rx_register()
476 rcv->sk = sk; in can_rx_register()
478 hlist_add_head_rcu(&rcv->list, rcv_list); in can_rx_register()
479 dev_rcv_lists->entries++; in can_rx_register()
481 rcv_lists_stats->rcv_entries++; in can_rx_register()
482 rcv_lists_stats->rcv_entries_max = max(rcv_lists_stats->rcv_entries_max, in can_rx_register()
483 rcv_lists_stats->rcv_entries); in can_rx_register()
484 spin_unlock_bh(&net->can.rcvlists_lock); in can_rx_register()
490 /* can_rx_delete_receiver - rcu callback for single receiver entry removal */
494 struct sock *sk = rcv->sk; in can_rx_delete_receiver()
502 * can_rx_unregister - unsubscribe CAN frames from a specific interface
519 struct can_rcv_lists_stats *rcv_lists_stats = net->can.rcv_lists_stats; in can_rx_unregister()
522 if (dev && dev->type != ARPHRD_CAN) in can_rx_unregister()
528 spin_lock_bh(&net->can.rcvlists_lock); in can_rx_unregister()
538 if (rcv->can_id == can_id && rcv->mask == mask && in can_rx_unregister()
539 rcv->func == func && rcv->data == data) in can_rx_unregister()
555 hlist_del_rcu(&rcv->list); in can_rx_unregister()
556 dev_rcv_lists->entries--; in can_rx_unregister()
558 if (rcv_lists_stats->rcv_entries > 0) in can_rx_unregister()
559 rcv_lists_stats->rcv_entries--; in can_rx_unregister()
562 spin_unlock_bh(&net->can.rcvlists_lock); in can_rx_unregister()
566 if (rcv->sk) in can_rx_unregister()
567 sock_hold(rcv->sk); in can_rx_unregister()
568 call_rcu(&rcv->rcu, can_rx_delete_receiver); in can_rx_unregister()
575 rcv->func(skb, rcv->data); in deliver()
576 rcv->matches++; in deliver()
583 struct can_frame *cf = (struct can_frame *)skb->data; in can_rcv_filter()
584 canid_t can_id = cf->can_id; in can_rcv_filter()
586 if (dev_rcv_lists->entries == 0) in can_rcv_filter()
591 hlist_for_each_entry_rcu(rcv, &dev_rcv_lists->rx[RX_ERR], list) { in can_rcv_filter()
592 if (can_id & rcv->mask) { in can_rcv_filter()
601 hlist_for_each_entry_rcu(rcv, &dev_rcv_lists->rx[RX_ALL], list) { in can_rcv_filter()
607 hlist_for_each_entry_rcu(rcv, &dev_rcv_lists->rx[RX_FIL], list) { in can_rcv_filter()
608 if ((can_id & rcv->mask) == rcv->can_id) { in can_rcv_filter()
614 /* check for inverted can_id/mask entries */ in can_rcv_filter()
615 hlist_for_each_entry_rcu(rcv, &dev_rcv_lists->rx[RX_INV], list) { in can_rcv_filter()
616 if ((can_id & rcv->mask) != rcv->can_id) { in can_rcv_filter()
622 /* check filterlists for single non-RTR can_ids */ in can_rcv_filter()
627 hlist_for_each_entry_rcu(rcv, &dev_rcv_lists->rx_eff[effhash(can_id)], list) { in can_rcv_filter()
628 if (rcv->can_id == can_id) { in can_rcv_filter()
635 hlist_for_each_entry_rcu(rcv, &dev_rcv_lists->rx_sff[can_id], list) { in can_rcv_filter()
648 struct can_pkg_stats *pkg_stats = net->can.pkg_stats; in can_receive()
652 atomic_long_inc(&pkg_stats->rx_frames); in can_receive()
653 atomic_long_inc(&pkg_stats->rx_frames_delta); in can_receive()
655 /* create non-zero unique skb identifier together with *skb */ in can_receive()
656 while (!(can_skb_prv(skb)->skbcnt)) in can_receive()
657 can_skb_prv(skb)->skbcnt = atomic_inc_return(&skbcounter); in can_receive()
662 matches = can_rcv_filter(net->can.rx_alldev_list, skb); in can_receive()
674 atomic_long_inc(&pkg_stats->matches); in can_receive()
675 atomic_long_inc(&pkg_stats->matches_delta); in can_receive()
682 if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_can_skb(skb))) { in can_rcv()
684 dev->type, skb->len); in can_rcv()
697 if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_canfd_skb(skb))) { in canfd_rcv()
699 dev->type, skb->len); in canfd_rcv()
712 if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_canxl_skb(skb))) { in canxl_rcv()
714 dev->type, skb->len); in canxl_rcv()
727 * can_proto_register - register CAN transport protocol
732 * -EINVAL invalid (out of range) protocol number
733 * -EBUSY protocol already in use
734 * -ENOBUF if proto_register() fails
738 int proto = cp->protocol; in can_proto_register()
743 return -EINVAL; in can_proto_register()
746 err = proto_register(cp->prot, 0); in can_proto_register()
754 err = -EBUSY; in can_proto_register()
762 proto_unregister(cp->prot); in can_proto_register()
769 * can_proto_unregister - unregister CAN transport protocol
774 int proto = cp->protocol; in can_proto_unregister()
783 proto_unregister(cp->prot); in can_proto_unregister()
789 spin_lock_init(&net->can.rcvlists_lock); in can_pernet_init()
790 net->can.rx_alldev_list = in can_pernet_init()
791 kzalloc(sizeof(*net->can.rx_alldev_list), GFP_KERNEL); in can_pernet_init()
792 if (!net->can.rx_alldev_list) in can_pernet_init()
794 net->can.pkg_stats = kzalloc(sizeof(*net->can.pkg_stats), GFP_KERNEL); in can_pernet_init()
795 if (!net->can.pkg_stats) in can_pernet_init()
797 net->can.rcv_lists_stats = kzalloc(sizeof(*net->can.rcv_lists_stats), GFP_KERNEL); in can_pernet_init()
798 if (!net->can.rcv_lists_stats) in can_pernet_init()
804 timer_setup(&net->can.stattimer, can_stat_update, in can_pernet_init()
806 mod_timer(&net->can.stattimer, in can_pernet_init()
809 net->can.pkg_stats->jiffies_init = jiffies; in can_pernet_init()
816 kfree(net->can.pkg_stats); in can_pernet_init()
818 kfree(net->can.rx_alldev_list); in can_pernet_init()
820 return -ENOMEM; in can_pernet_init()
828 timer_delete_sync(&net->can.stattimer); in can_pernet_exit()
831 kfree(net->can.rx_alldev_list); in can_pernet_exit()
832 kfree(net->can.pkg_stats); in can_pernet_exit()
833 kfree(net->can.rcv_lists_stats); in can_pernet_exit()
881 return -ENOMEM; in can_init()