Commit 24bf50bc89088686a40cb4ed7f21bd0d08ce6b0b

Authored by Oliver Hartkopp
Committed by Greg Kroah-Hartman
1 parent 9b68f12b57

can: fix handling of unmodifiable configuration options

commit bb208f144cf3f59d8f89a09a80efd04389718907 upstream.

As described in 'can: m_can: tag current CAN FD controllers as non-ISO'
(6cfda7fbebe) it is possible to define fixed configuration options by
setting the according bit in 'ctrlmode' and clear it in 'ctrlmode_supported'.
This leads to the incovenience that the fixed configuration bits can not be
passed by netlink even when they have the correct values (e.g. non-ISO, FD).

This patch fixes that issue and not only allows fixed set bit values to be set
again but now requires(!) to provide these fixed values at configuration time.
A valid CAN FD configuration consists of a nominal/arbitration bittiming, a
data bittiming and a control mode with CAN_CTRLMODE_FD set - which is now
enforced by a new can_validate() function. This fix additionally removed the
inconsistency that was prohibiting the support of 'CANFD-only' controller
drivers, like the RCar CAN FD.

For this reason a new helper can_set_static_ctrlmode() has been introduced to
provide a proper interface to handle static enabled CAN controller options.

Reported-by: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Reviewed-by: Ramesh Shanmugasundaram  <ramesh.shanmugasundaram@bp.renesas.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 3 changed files with 73 additions and 7 deletions Side-by-side Diff

drivers/net/can/dev.c
... ... @@ -696,11 +696,17 @@
696 696 /* allow change of MTU according to the CANFD ability of the device */
697 697 switch (new_mtu) {
698 698 case CAN_MTU:
  699 + /* 'CANFD-only' controllers can not switch to CAN_MTU */
  700 + if (priv->ctrlmode_static & CAN_CTRLMODE_FD)
  701 + return -EINVAL;
  702 +
699 703 priv->ctrlmode &= ~CAN_CTRLMODE_FD;
700 704 break;
701 705  
702 706 case CANFD_MTU:
703   - if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD))
  707 + /* check for potential CANFD ability */
  708 + if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD) &&
  709 + !(priv->ctrlmode_static & CAN_CTRLMODE_FD))
704 710 return -EINVAL;
705 711  
706 712 priv->ctrlmode |= CAN_CTRLMODE_FD;
... ... @@ -782,6 +788,35 @@
782 788 = { .len = sizeof(struct can_bittiming_const) },
783 789 };
784 790  
  791 +static int can_validate(struct nlattr *tb[], struct nlattr *data[])
  792 +{
  793 + bool is_can_fd = false;
  794 +
  795 + /* Make sure that valid CAN FD configurations always consist of
  796 + * - nominal/arbitration bittiming
  797 + * - data bittiming
  798 + * - control mode with CAN_CTRLMODE_FD set
  799 + */
  800 +
  801 + if (data[IFLA_CAN_CTRLMODE]) {
  802 + struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
  803 +
  804 + is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD;
  805 + }
  806 +
  807 + if (is_can_fd) {
  808 + if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING])
  809 + return -EOPNOTSUPP;
  810 + }
  811 +
  812 + if (data[IFLA_CAN_DATA_BITTIMING]) {
  813 + if (!is_can_fd || !data[IFLA_CAN_BITTIMING])
  814 + return -EOPNOTSUPP;
  815 + }
  816 +
  817 + return 0;
  818 +}
  819 +
785 820 static int can_changelink(struct net_device *dev,
786 821 struct nlattr *tb[], struct nlattr *data[])
787 822 {
788 823  
789 824  
790 825  
791 826  
... ... @@ -813,19 +848,31 @@
813 848  
814 849 if (data[IFLA_CAN_CTRLMODE]) {
815 850 struct can_ctrlmode *cm;
  851 + u32 ctrlstatic;
  852 + u32 maskedflags;
816 853  
817 854 /* Do not allow changing controller mode while running */
818 855 if (dev->flags & IFF_UP)
819 856 return -EBUSY;
820 857 cm = nla_data(data[IFLA_CAN_CTRLMODE]);
  858 + ctrlstatic = priv->ctrlmode_static;
  859 + maskedflags = cm->flags & cm->mask;
821 860  
822   - /* check whether changed bits are allowed to be modified */
823   - if (cm->mask & ~priv->ctrlmode_supported)
  861 + /* check whether provided bits are allowed to be passed */
  862 + if (cm->mask & ~(priv->ctrlmode_supported | ctrlstatic))
824 863 return -EOPNOTSUPP;
825 864  
  865 + /* do not check for static fd-non-iso if 'fd' is disabled */
  866 + if (!(maskedflags & CAN_CTRLMODE_FD))
  867 + ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO;
  868 +
  869 + /* make sure static options are provided by configuration */
  870 + if ((maskedflags & ctrlstatic) != ctrlstatic)
  871 + return -EOPNOTSUPP;
  872 +
826 873 /* clear bits to be modified and copy the flag values */
827 874 priv->ctrlmode &= ~cm->mask;
828   - priv->ctrlmode |= (cm->flags & cm->mask);
  875 + priv->ctrlmode |= maskedflags;
829 876  
830 877 /* CAN_CTRLMODE_FD can only be set when driver supports FD */
831 878 if (priv->ctrlmode & CAN_CTRLMODE_FD)
... ... @@ -966,6 +1013,7 @@
966 1013 .maxtype = IFLA_CAN_MAX,
967 1014 .policy = can_policy,
968 1015 .setup = can_setup,
  1016 + .validate = can_validate,
969 1017 .newlink = can_newlink,
970 1018 .changelink = can_changelink,
971 1019 .get_size = can_get_size,
drivers/net/can/m_can/m_can.c
... ... @@ -955,7 +955,7 @@
955 955 priv->can.do_get_berr_counter = m_can_get_berr_counter;
956 956  
957 957 /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.1 */
958   - priv->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO;
  958 + can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO);
959 959  
960 960 /* CAN_CTRLMODE_FD_NON_ISO can not be changed with M_CAN IP v3.0.1 */
961 961 priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
include/linux/can/dev.h
... ... @@ -40,9 +40,12 @@
40 40 struct can_clock clock;
41 41  
42 42 enum can_state state;
43   - u32 ctrlmode;
44   - u32 ctrlmode_supported;
45 43  
  44 + /* CAN controller features - see include/uapi/linux/can/netlink.h */
  45 + u32 ctrlmode; /* current options setting */
  46 + u32 ctrlmode_supported; /* options that can be modified by netlink */
  47 + u32 ctrlmode_static; /* static enabled options for driver/hardware */
  48 +
46 49 int restart_ms;
47 50 struct timer_list restart_timer;
48 51  
... ... @@ -106,6 +109,21 @@
106 109 {
107 110 /* the CAN specific type of skb is identified by its data length */
108 111 return skb->len == CANFD_MTU;
  112 +}
  113 +
  114 +/* helper to define static CAN controller features at device creation time */
  115 +static inline void can_set_static_ctrlmode(struct net_device *dev,
  116 + u32 static_mode)
  117 +{
  118 + struct can_priv *priv = netdev_priv(dev);
  119 +
  120 + /* alloc_candev() succeeded => netdev_priv() is valid at this point */
  121 + priv->ctrlmode = static_mode;
  122 + priv->ctrlmode_static = static_mode;
  123 +
  124 + /* override MTU which was set by default in can_setup()? */
  125 + if (static_mode & CAN_CTRLMODE_FD)
  126 + dev->mtu = CANFD_MTU;
109 127 }
110 128  
111 129 /* get data length from can_dlc with sanitized can_dlc */