diff options
author | David S. Miller <davem@davemloft.net> | 2013-11-04 19:59:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-11-04 19:59:44 -0500 |
commit | 13521a57974635384db51d65135cc0267c6ae771 (patch) | |
tree | 7efbad661e4cdbb5e469dcb7c64e5b35ddc0266a | |
parent | 9f9843a751d0a2057f9f3d313886e7e5e6ebaac9 (diff) | |
parent | 26896fd98130cdda73b19c75849a0d25cb850cb8 (diff) |
Merge branch 'for-davem' of git://gitorious.org/linux-can/linux-can-next
Marc Kleine-Budde says:
====================
here's a pull request for net-next.
It includes a patch by Oliver Hartkopp et al. that adds documentation
for the broadcast manager to Documentation/networking/can.txt. Three
patches by me that clean up the netlink handling code in the CAN core.
And another patch that removes a not needed function from the ti_hecc
driver.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/networking/can.txt | 217 | ||||
-rw-r--r-- | drivers/net/can/dev.c | 67 | ||||
-rw-r--r-- | drivers/net/can/ti_hecc.c | 10 |
3 files changed, 249 insertions, 45 deletions
diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index 820f55344edc..4c072414eadb 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt | |||
@@ -25,6 +25,12 @@ This file contains | |||
25 | 4.1.5 RAW socket option CAN_RAW_FD_FRAMES | 25 | 4.1.5 RAW socket option CAN_RAW_FD_FRAMES |
26 | 4.1.6 RAW socket returned message flags | 26 | 4.1.6 RAW socket returned message flags |
27 | 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) | 27 | 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) |
28 | 4.2.1 Broadcast Manager operations | ||
29 | 4.2.2 Broadcast Manager message flags | ||
30 | 4.2.3 Broadcast Manager transmission timers | ||
31 | 4.2.4 Broadcast Manager message sequence transmission | ||
32 | 4.2.5 Broadcast Manager receive filter timers | ||
33 | 4.2.6 Broadcast Manager multiplex message receive filter | ||
28 | 4.3 connected transport protocols (SOCK_SEQPACKET) | 34 | 4.3 connected transport protocols (SOCK_SEQPACKET) |
29 | 4.4 unconnected transport protocols (SOCK_DGRAM) | 35 | 4.4 unconnected transport protocols (SOCK_DGRAM) |
30 | 36 | ||
@@ -593,6 +599,217 @@ solution for a couple of reasons: | |||
593 | In order to receive such messages, CAN_RAW_RECV_OWN_MSGS must be set. | 599 | In order to receive such messages, CAN_RAW_RECV_OWN_MSGS must be set. |
594 | 600 | ||
595 | 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) | 601 | 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) |
602 | |||
603 | The Broadcast Manager protocol provides a command based configuration | ||
604 | interface to filter and send (e.g. cyclic) CAN messages in kernel space. | ||
605 | |||
606 | Receive filters can be used to down sample frequent messages; detect events | ||
607 | such as message contents changes, packet length changes, and do time-out | ||
608 | monitoring of received messages. | ||
609 | |||
610 | Periodic transmission tasks of CAN frames or a sequence of CAN frames can be | ||
611 | created and modified at runtime; both the message content and the two | ||
612 | possible transmit intervals can be altered. | ||
613 | |||
614 | A BCM socket is not intended for sending individual CAN frames using the | ||
615 | struct can_frame as known from the CAN_RAW socket. Instead a special BCM | ||
616 | configuration message is defined. The basic BCM configuration message used | ||
617 | to communicate with the broadcast manager and the available operations are | ||
618 | defined in the linux/can/bcm.h include. The BCM message consists of a | ||
619 | message header with a command ('opcode') followed by zero or more CAN frames. | ||
620 | The broadcast manager sends responses to user space in the same form: | ||
621 | |||
622 | struct bcm_msg_head { | ||
623 | __u32 opcode; /* command */ | ||
624 | __u32 flags; /* special flags */ | ||
625 | __u32 count; /* run 'count' times with ival1 */ | ||
626 | struct timeval ival1, ival2; /* count and subsequent interval */ | ||
627 | canid_t can_id; /* unique can_id for task */ | ||
628 | __u32 nframes; /* number of can_frames following */ | ||
629 | struct can_frame frames[0]; | ||
630 | }; | ||
631 | |||
632 | The aligned payload 'frames' uses the same basic CAN frame structure defined | ||
633 | at the beginning of section 4 and in the include/linux/can.h include. All | ||
634 | messages to the broadcast manager from user space have this structure. | ||
635 | |||
636 | Note a CAN_BCM socket must be connected instead of bound after socket | ||
637 | creation (example without error checking): | ||
638 | |||
639 | int s; | ||
640 | struct sockaddr_can addr; | ||
641 | struct ifreq ifr; | ||
642 | |||
643 | s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM); | ||
644 | |||
645 | strcpy(ifr.ifr_name, "can0"); | ||
646 | ioctl(s, SIOCGIFINDEX, &ifr); | ||
647 | |||
648 | addr.can_family = AF_CAN; | ||
649 | addr.can_ifindex = ifr.ifr_ifindex; | ||
650 | |||
651 | connect(s, (struct sockaddr *)&addr, sizeof(addr)) | ||
652 | |||
653 | (..) | ||
654 | |||
655 | The broadcast manager socket is able to handle any number of in flight | ||
656 | transmissions or receive filters concurrently. The different RX/TX jobs are | ||
657 | distinguished by the unique can_id in each BCM message. However additional | ||
658 | CAN_BCM sockets are recommended to communicate on multiple CAN interfaces. | ||
659 | When the broadcast manager socket is bound to 'any' CAN interface (=> the | ||
660 | interface index is set to zero) the configured receive filters apply to any | ||
661 | CAN interface unless the sendto() syscall is used to overrule the 'any' CAN | ||
662 | interface index. When using recvfrom() instead of read() to retrieve BCM | ||
663 | socket messages the originating CAN interface is provided in can_ifindex. | ||
664 | |||
665 | 4.2.1 Broadcast Manager operations | ||
666 | |||
667 | The opcode defines the operation for the broadcast manager to carry out, | ||
668 | or details the broadcast managers response to several events, including | ||
669 | user requests. | ||
670 | |||
671 | Transmit Operations (user space to broadcast manager): | ||
672 | |||
673 | TX_SETUP: Create (cyclic) transmission task. | ||
674 | |||
675 | TX_DELETE: Remove (cyclic) transmission task, requires only can_id. | ||
676 | |||
677 | TX_READ: Read properties of (cyclic) transmission task for can_id. | ||
678 | |||
679 | TX_SEND: Send one CAN frame. | ||
680 | |||
681 | Transmit Responses (broadcast manager to user space): | ||
682 | |||
683 | TX_STATUS: Reply to TX_READ request (transmission task configuration). | ||
684 | |||
685 | TX_EXPIRED: Notification when counter finishes sending at initial interval | ||
686 | 'ival1'. Requires the TX_COUNTEVT flag to be set at TX_SETUP. | ||
687 | |||
688 | Receive Operations (user space to broadcast manager): | ||
689 | |||
690 | RX_SETUP: Create RX content filter subscription. | ||
691 | |||
692 | RX_DELETE: Remove RX content filter subscription, requires only can_id. | ||
693 | |||
694 | RX_READ: Read properties of RX content filter subscription for can_id. | ||
695 | |||
696 | Receive Responses (broadcast manager to user space): | ||
697 | |||
698 | RX_STATUS: Reply to RX_READ request (filter task configuration). | ||
699 | |||
700 | RX_TIMEOUT: Cyclic message is detected to be absent (timer ival1 expired). | ||
701 | |||
702 | RX_CHANGED: BCM message with updated CAN frame (detected content change). | ||
703 | Sent on first message received or on receipt of revised CAN messages. | ||
704 | |||
705 | 4.2.2 Broadcast Manager message flags | ||
706 | |||
707 | When sending a message to the broadcast manager the 'flags' element may | ||
708 | contain the following flag definitions which influence the behaviour: | ||
709 | |||
710 | SETTIMER: Set the values of ival1, ival2 and count | ||
711 | |||
712 | STARTTIMER: Start the timer with the actual values of ival1, ival2 | ||
713 | and count. Starting the timer leads simultaneously to emit a CAN frame. | ||
714 | |||
715 | TX_COUNTEVT: Create the message TX_EXPIRED when count expires | ||
716 | |||
717 | TX_ANNOUNCE: A change of data by the process is emitted immediately. | ||
718 | |||
719 | TX_CP_CAN_ID: Copies the can_id from the message header to each | ||
720 | subsequent frame in frames. This is intended as usage simplification. For | ||
721 | TX tasks the unique can_id from the message header may differ from the | ||
722 | can_id(s) stored for transmission in the subsequent struct can_frame(s). | ||
723 | |||
724 | RX_FILTER_ID: Filter by can_id alone, no frames required (nframes=0). | ||
725 | |||
726 | RX_CHECK_DLC: A change of the DLC leads to an RX_CHANGED. | ||
727 | |||
728 | RX_NO_AUTOTIMER: Prevent automatically starting the timeout monitor. | ||
729 | |||
730 | RX_ANNOUNCE_RESUME: If passed at RX_SETUP and a receive timeout occured, a | ||
731 | RX_CHANGED message will be generated when the (cyclic) receive restarts. | ||
732 | |||
733 | TX_RESET_MULTI_IDX: Reset the index for the multiple frame transmission. | ||
734 | |||
735 | RX_RTR_FRAME: Send reply for RTR-request (placed in op->frames[0]). | ||
736 | |||
737 | 4.2.3 Broadcast Manager transmission timers | ||
738 | |||
739 | Periodic transmission configurations may use up to two interval timers. | ||
740 | In this case the BCM sends a number of messages ('count') at an interval | ||
741 | 'ival1', then continuing to send at another given interval 'ival2'. When | ||
742 | only one timer is needed 'count' is set to zero and only 'ival2' is used. | ||
743 | When SET_TIMER and START_TIMER flag were set the timers are activated. | ||
744 | The timer values can be altered at runtime when only SET_TIMER is set. | ||
745 | |||
746 | 4.2.4 Broadcast Manager message sequence transmission | ||
747 | |||
748 | Up to 256 CAN frames can be transmitted in a sequence in the case of a cyclic | ||
749 | TX task configuration. The number of CAN frames is provided in the 'nframes' | ||
750 | element of the BCM message head. The defined number of CAN frames are added | ||
751 | as array to the TX_SETUP BCM configuration message. | ||
752 | |||
753 | /* create a struct to set up a sequence of four CAN frames */ | ||
754 | struct { | ||
755 | struct bcm_msg_head msg_head; | ||
756 | struct can_frame frame[4]; | ||
757 | } mytxmsg; | ||
758 | |||
759 | (..) | ||
760 | mytxmsg.nframes = 4; | ||
761 | (..) | ||
762 | |||
763 | write(s, &mytxmsg, sizeof(mytxmsg)); | ||
764 | |||
765 | With every transmission the index in the array of CAN frames is increased | ||
766 | and set to zero at index overflow. | ||
767 | |||
768 | 4.2.5 Broadcast Manager receive filter timers | ||
769 | |||
770 | The timer values ival1 or ival2 may be set to non-zero values at RX_SETUP. | ||
771 | When the SET_TIMER flag is set the timers are enabled: | ||
772 | |||
773 | ival1: Send RX_TIMEOUT when a received message is not received again within | ||
774 | the given time. When START_TIMER is set at RX_SETUP the timeout detection | ||
775 | is activated directly - even without a former CAN frame reception. | ||
776 | |||
777 | ival2: Throttle the received message rate down to the value of ival2. This | ||
778 | is useful to reduce messages for the application when the signal inside the | ||
779 | CAN frame is stateless as state changes within the ival2 periode may get | ||
780 | lost. | ||
781 | |||
782 | 4.2.6 Broadcast Manager multiplex message receive filter | ||
783 | |||
784 | To filter for content changes in multiplex message sequences an array of more | ||
785 | than one CAN frames can be passed in a RX_SETUP configuration message. The | ||
786 | data bytes of the first CAN frame contain the mask of relevant bits that | ||
787 | have to match in the subsequent CAN frames with the received CAN frame. | ||
788 | If one of the subsequent CAN frames is matching the bits in that frame data | ||
789 | mark the relevant content to be compared with the previous received content. | ||
790 | Up to 257 CAN frames (multiplex filter bit mask CAN frame plus 256 CAN | ||
791 | filters) can be added as array to the TX_SETUP BCM configuration message. | ||
792 | |||
793 | /* usually used to clear CAN frame data[] - beware of endian problems! */ | ||
794 | #define U64_DATA(p) (*(unsigned long long*)(p)->data) | ||
795 | |||
796 | struct { | ||
797 | struct bcm_msg_head msg_head; | ||
798 | struct can_frame frame[5]; | ||
799 | } msg; | ||
800 | |||
801 | msg.msg_head.opcode = RX_SETUP; | ||
802 | msg.msg_head.can_id = 0x42; | ||
803 | msg.msg_head.flags = 0; | ||
804 | msg.msg_head.nframes = 5; | ||
805 | U64_DATA(&msg.frame[0]) = 0xFF00000000000000ULL; /* MUX mask */ | ||
806 | U64_DATA(&msg.frame[1]) = 0x01000000000000FFULL; /* data mask (MUX 0x01) */ | ||
807 | U64_DATA(&msg.frame[2]) = 0x0200FFFF000000FFULL; /* data mask (MUX 0x02) */ | ||
808 | U64_DATA(&msg.frame[3]) = 0x330000FFFFFF0003ULL; /* data mask (MUX 0x33) */ | ||
809 | U64_DATA(&msg.frame[4]) = 0x4F07FC0FF0000000ULL; /* data mask (MUX 0x4F) */ | ||
810 | |||
811 | write(s, &msg, sizeof(msg)); | ||
812 | |||
596 | 4.3 connected transport protocols (SOCK_SEQPACKET) | 813 | 4.3 connected transport protocols (SOCK_SEQPACKET) |
597 | 4.4 unconnected transport protocols (SOCK_DGRAM) | 814 | 4.4 unconnected transport protocols (SOCK_DGRAM) |
598 | 815 | ||
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 1870c4731a57..bda1888cae9a 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -645,19 +645,6 @@ static int can_changelink(struct net_device *dev, | |||
645 | /* We need synchronization with dev->stop() */ | 645 | /* We need synchronization with dev->stop() */ |
646 | ASSERT_RTNL(); | 646 | ASSERT_RTNL(); |
647 | 647 | ||
648 | if (data[IFLA_CAN_CTRLMODE]) { | ||
649 | struct can_ctrlmode *cm; | ||
650 | |||
651 | /* Do not allow changing controller mode while running */ | ||
652 | if (dev->flags & IFF_UP) | ||
653 | return -EBUSY; | ||
654 | cm = nla_data(data[IFLA_CAN_CTRLMODE]); | ||
655 | if (cm->flags & ~priv->ctrlmode_supported) | ||
656 | return -EOPNOTSUPP; | ||
657 | priv->ctrlmode &= ~cm->mask; | ||
658 | priv->ctrlmode |= cm->flags; | ||
659 | } | ||
660 | |||
661 | if (data[IFLA_CAN_BITTIMING]) { | 648 | if (data[IFLA_CAN_BITTIMING]) { |
662 | struct can_bittiming bt; | 649 | struct can_bittiming bt; |
663 | 650 | ||
@@ -680,6 +667,19 @@ static int can_changelink(struct net_device *dev, | |||
680 | } | 667 | } |
681 | } | 668 | } |
682 | 669 | ||
670 | if (data[IFLA_CAN_CTRLMODE]) { | ||
671 | struct can_ctrlmode *cm; | ||
672 | |||
673 | /* Do not allow changing controller mode while running */ | ||
674 | if (dev->flags & IFF_UP) | ||
675 | return -EBUSY; | ||
676 | cm = nla_data(data[IFLA_CAN_CTRLMODE]); | ||
677 | if (cm->flags & ~priv->ctrlmode_supported) | ||
678 | return -EOPNOTSUPP; | ||
679 | priv->ctrlmode &= ~cm->mask; | ||
680 | priv->ctrlmode |= cm->flags; | ||
681 | } | ||
682 | |||
683 | if (data[IFLA_CAN_RESTART_MS]) { | 683 | if (data[IFLA_CAN_RESTART_MS]) { |
684 | /* Do not allow changing restart delay while running */ | 684 | /* Do not allow changing restart delay while running */ |
685 | if (dev->flags & IFF_UP) | 685 | if (dev->flags & IFF_UP) |
@@ -702,17 +702,17 @@ static int can_changelink(struct net_device *dev, | |||
702 | static size_t can_get_size(const struct net_device *dev) | 702 | static size_t can_get_size(const struct net_device *dev) |
703 | { | 703 | { |
704 | struct can_priv *priv = netdev_priv(dev); | 704 | struct can_priv *priv = netdev_priv(dev); |
705 | size_t size; | 705 | size_t size = 0; |
706 | 706 | ||
707 | size = nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */ | 707 | size += nla_total_size(sizeof(struct can_bittiming)); /* IFLA_CAN_BITTIMING */ |
708 | size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */ | 708 | if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ |
709 | size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ | ||
710 | size += nla_total_size(sizeof(struct can_bittiming)); /* IFLA_CAN_BITTIMING */ | ||
711 | size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ | ||
712 | if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ | ||
713 | size += nla_total_size(sizeof(struct can_berr_counter)); | ||
714 | if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ | ||
715 | size += nla_total_size(sizeof(struct can_bittiming_const)); | 709 | size += nla_total_size(sizeof(struct can_bittiming_const)); |
710 | size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ | ||
711 | size += nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */ | ||
712 | size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */ | ||
713 | size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ | ||
714 | if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ | ||
715 | size += nla_total_size(sizeof(struct can_berr_counter)); | ||
716 | 716 | ||
717 | return size; | 717 | return size; |
718 | } | 718 | } |
@@ -726,23 +726,20 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) | |||
726 | 726 | ||
727 | if (priv->do_get_state) | 727 | if (priv->do_get_state) |
728 | priv->do_get_state(dev, &state); | 728 | priv->do_get_state(dev, &state); |
729 | if (nla_put_u32(skb, IFLA_CAN_STATE, state) || | 729 | if (nla_put(skb, IFLA_CAN_BITTIMING, |
730 | nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || | ||
731 | nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || | ||
732 | nla_put(skb, IFLA_CAN_BITTIMING, | ||
733 | sizeof(priv->bittiming), &priv->bittiming) || | 730 | sizeof(priv->bittiming), &priv->bittiming) || |
731 | (priv->bittiming_const && | ||
732 | nla_put(skb, IFLA_CAN_BITTIMING_CONST, | ||
733 | sizeof(*priv->bittiming_const), priv->bittiming_const)) || | ||
734 | nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) || | 734 | nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) || |
735 | nla_put_u32(skb, IFLA_CAN_STATE, state) || | ||
736 | nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || | ||
737 | nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || | ||
735 | (priv->do_get_berr_counter && | 738 | (priv->do_get_berr_counter && |
736 | !priv->do_get_berr_counter(dev, &bec) && | 739 | !priv->do_get_berr_counter(dev, &bec) && |
737 | nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) || | 740 | nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec))) |
738 | (priv->bittiming_const && | 741 | return -EMSGSIZE; |
739 | nla_put(skb, IFLA_CAN_BITTIMING_CONST, | ||
740 | sizeof(*priv->bittiming_const), priv->bittiming_const))) | ||
741 | goto nla_put_failure; | ||
742 | return 0; | 742 | return 0; |
743 | |||
744 | nla_put_failure: | ||
745 | return -EMSGSIZE; | ||
746 | } | 743 | } |
747 | 744 | ||
748 | static size_t can_get_xstats_size(const struct net_device *dev) | 745 | static size_t can_get_xstats_size(const struct net_device *dev) |
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index beb5ef834f0f..60d95b44d0f7 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c | |||
@@ -286,15 +286,6 @@ static inline u32 hecc_get_bit(struct ti_hecc_priv *priv, int reg, u32 bit_mask) | |||
286 | return (hecc_read(priv, reg) & bit_mask) ? 1 : 0; | 286 | return (hecc_read(priv, reg) & bit_mask) ? 1 : 0; |
287 | } | 287 | } |
288 | 288 | ||
289 | static int ti_hecc_get_state(const struct net_device *ndev, | ||
290 | enum can_state *state) | ||
291 | { | ||
292 | struct ti_hecc_priv *priv = netdev_priv(ndev); | ||
293 | |||
294 | *state = priv->can.state; | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static int ti_hecc_set_btc(struct ti_hecc_priv *priv) | 289 | static int ti_hecc_set_btc(struct ti_hecc_priv *priv) |
299 | { | 290 | { |
300 | struct can_bittiming *bit_timing = &priv->can.bittiming; | 291 | struct can_bittiming *bit_timing = &priv->can.bittiming; |
@@ -940,7 +931,6 @@ static int ti_hecc_probe(struct platform_device *pdev) | |||
940 | 931 | ||
941 | priv->can.bittiming_const = &ti_hecc_bittiming_const; | 932 | priv->can.bittiming_const = &ti_hecc_bittiming_const; |
942 | priv->can.do_set_mode = ti_hecc_do_set_mode; | 933 | priv->can.do_set_mode = ti_hecc_do_set_mode; |
943 | priv->can.do_get_state = ti_hecc_get_state; | ||
944 | priv->can.do_get_berr_counter = ti_hecc_get_berr_counter; | 934 | priv->can.do_get_berr_counter = ti_hecc_get_berr_counter; |
945 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; | 935 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; |
946 | 936 | ||