@@ -279,25 +279,45 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
279
279
return 0 ;
280
280
}
281
281
282
+ /* Checks the validity of predefined bitrate settings */
283
+ static int can_validate_bitrate (struct net_device * dev , struct can_bittiming * bt ,
284
+ const u32 * bitrate_const ,
285
+ const unsigned int bitrate_const_cnt )
286
+ {
287
+ struct can_priv * priv = netdev_priv (dev );
288
+ unsigned int i ;
289
+
290
+ for (i = 0 ; i < bitrate_const_cnt ; i ++ ) {
291
+ if (bt -> bitrate == bitrate_const [i ])
292
+ break ;
293
+ }
294
+
295
+ if (i >= priv -> bitrate_const_cnt )
296
+ return - EINVAL ;
297
+
298
+ return 0 ;
299
+ }
300
+
282
301
static int can_get_bittiming (struct net_device * dev , struct can_bittiming * bt ,
283
- const struct can_bittiming_const * btc )
302
+ const struct can_bittiming_const * btc ,
303
+ const u32 * bitrate_const ,
304
+ const unsigned int bitrate_const_cnt )
284
305
{
285
306
int err ;
286
307
287
- /* Check if the CAN device has bit-timing parameters */
288
- if (!btc )
289
- return - EOPNOTSUPP ;
290
-
291
308
/*
292
309
* Depending on the given can_bittiming parameter structure the CAN
293
310
* timing parameters are calculated based on the provided bitrate OR
294
311
* alternatively the CAN timing parameters (tq, prop_seg, etc.) are
295
312
* provided directly which are then checked and fixed up.
296
313
*/
297
- if (!bt -> tq && bt -> bitrate )
314
+ if (!bt -> tq && bt -> bitrate && btc )
298
315
err = can_calc_bittiming (dev , bt , btc );
299
- else if (bt -> tq && !bt -> bitrate )
316
+ else if (bt -> tq && !bt -> bitrate && btc )
300
317
err = can_fixup_bittiming (dev , bt , btc );
318
+ else if (!bt -> tq && bt -> bitrate && bitrate_const )
319
+ err = can_validate_bitrate (dev , bt , bitrate_const ,
320
+ bitrate_const_cnt );
301
321
else
302
322
err = - EINVAL ;
303
323
@@ -872,8 +892,20 @@ static int can_changelink(struct net_device *dev,
872
892
/* Do not allow changing bittiming while running */
873
893
if (dev -> flags & IFF_UP )
874
894
return - EBUSY ;
895
+
896
+ /* Calculate bittiming parameters based on
897
+ * bittiming_const if set, otherwise pass bitrate
898
+ * directly via do_set_bitrate(). Bail out if neither
899
+ * is given.
900
+ */
901
+ if (!priv -> bittiming_const && !priv -> do_set_bittiming )
902
+ return - EOPNOTSUPP ;
903
+
875
904
memcpy (& bt , nla_data (data [IFLA_CAN_BITTIMING ]), sizeof (bt ));
876
- err = can_get_bittiming (dev , & bt , priv -> bittiming_const );
905
+ err = can_get_bittiming (dev , & bt ,
906
+ priv -> bittiming_const ,
907
+ priv -> bitrate_const ,
908
+ priv -> bitrate_const_cnt );
877
909
if (err )
878
910
return err ;
879
911
memcpy (& priv -> bittiming , & bt , sizeof (bt ));
@@ -943,9 +975,21 @@ static int can_changelink(struct net_device *dev,
943
975
/* Do not allow changing bittiming while running */
944
976
if (dev -> flags & IFF_UP )
945
977
return - EBUSY ;
978
+
979
+ /* Calculate bittiming parameters based on
980
+ * data_bittiming_const if set, otherwise pass bitrate
981
+ * directly via do_set_bitrate(). Bail out if neither
982
+ * is given.
983
+ */
984
+ if (!priv -> data_bittiming_const && !priv -> do_set_data_bittiming )
985
+ return - EOPNOTSUPP ;
986
+
946
987
memcpy (& dbt , nla_data (data [IFLA_CAN_DATA_BITTIMING ]),
947
988
sizeof (dbt ));
948
- err = can_get_bittiming (dev , & dbt , priv -> data_bittiming_const );
989
+ err = can_get_bittiming (dev , & dbt ,
990
+ priv -> data_bittiming_const ,
991
+ priv -> data_bitrate_const ,
992
+ priv -> data_bitrate_const_cnt );
949
993
if (err )
950
994
return err ;
951
995
memcpy (& priv -> data_bittiming , & dbt , sizeof (dbt ));
@@ -958,6 +1002,30 @@ static int can_changelink(struct net_device *dev,
958
1002
}
959
1003
}
960
1004
1005
+ if (data [IFLA_CAN_TERMINATION ]) {
1006
+ const u16 termval = nla_get_u16 (data [IFLA_CAN_TERMINATION ]);
1007
+ const unsigned int num_term = priv -> termination_const_cnt ;
1008
+ unsigned int i ;
1009
+
1010
+ if (!priv -> do_set_termination )
1011
+ return - EOPNOTSUPP ;
1012
+
1013
+ /* check whether given value is supported by the interface */
1014
+ for (i = 0 ; i < num_term ; i ++ ) {
1015
+ if (termval == priv -> termination_const [i ])
1016
+ break ;
1017
+ }
1018
+ if (i >= num_term )
1019
+ return - EINVAL ;
1020
+
1021
+ /* Finally, set the termination value */
1022
+ err = priv -> do_set_termination (dev , termval );
1023
+ if (err )
1024
+ return err ;
1025
+
1026
+ priv -> termination = termval ;
1027
+ }
1028
+
961
1029
return 0 ;
962
1030
}
963
1031
@@ -980,6 +1048,17 @@ static size_t can_get_size(const struct net_device *dev)
980
1048
size += nla_total_size (sizeof (struct can_bittiming ));
981
1049
if (priv -> data_bittiming_const ) /* IFLA_CAN_DATA_BITTIMING_CONST */
982
1050
size += nla_total_size (sizeof (struct can_bittiming_const ));
1051
+ if (priv -> termination_const ) {
1052
+ size += nla_total_size (sizeof (priv -> termination )); /* IFLA_CAN_TERMINATION */
1053
+ size += nla_total_size (sizeof (* priv -> termination_const ) * /* IFLA_CAN_TERMINATION_CONST */
1054
+ priv -> termination_const_cnt );
1055
+ }
1056
+ if (priv -> bitrate_const ) /* IFLA_CAN_BITRATE_CONST */
1057
+ size += nla_total_size (sizeof (* priv -> bitrate_const ) *
1058
+ priv -> bitrate_const_cnt );
1059
+ if (priv -> data_bitrate_const ) /* IFLA_CAN_DATA_BITRATE_CONST */
1060
+ size += nla_total_size (sizeof (* priv -> data_bitrate_const ) *
1061
+ priv -> data_bitrate_const_cnt );
983
1062
984
1063
return size ;
985
1064
}
@@ -1018,7 +1097,28 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
1018
1097
(priv -> data_bittiming_const &&
1019
1098
nla_put (skb , IFLA_CAN_DATA_BITTIMING_CONST ,
1020
1099
sizeof (* priv -> data_bittiming_const ),
1021
- priv -> data_bittiming_const )))
1100
+ priv -> data_bittiming_const )) ||
1101
+
1102
+ (priv -> termination_const &&
1103
+ (nla_put_u16 (skb , IFLA_CAN_TERMINATION , priv -> termination ) ||
1104
+ nla_put (skb , IFLA_CAN_TERMINATION_CONST ,
1105
+ sizeof (* priv -> termination_const ) *
1106
+ priv -> termination_const_cnt ,
1107
+ priv -> termination_const ))) ||
1108
+
1109
+ (priv -> bitrate_const &&
1110
+ nla_put (skb , IFLA_CAN_BITRATE_CONST ,
1111
+ sizeof (* priv -> bitrate_const ) *
1112
+ priv -> bitrate_const_cnt ,
1113
+ priv -> bitrate_const )) ||
1114
+
1115
+ (priv -> data_bitrate_const &&
1116
+ nla_put (skb , IFLA_CAN_DATA_BITRATE_CONST ,
1117
+ sizeof (* priv -> data_bitrate_const ) *
1118
+ priv -> data_bitrate_const_cnt ,
1119
+ priv -> data_bitrate_const ))
1120
+ )
1121
+
1022
1122
return - EMSGSIZE ;
1023
1123
1024
1124
return 0 ;
@@ -1073,6 +1173,22 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
1073
1173
*/
1074
1174
int register_candev (struct net_device * dev )
1075
1175
{
1176
+ struct can_priv * priv = netdev_priv (dev );
1177
+
1178
+ /* Ensure termination_const, termination_const_cnt and
1179
+ * do_set_termination consistency. All must be either set or
1180
+ * unset.
1181
+ */
1182
+ if ((!priv -> termination_const != !priv -> termination_const_cnt ) ||
1183
+ (!priv -> termination_const != !priv -> do_set_termination ))
1184
+ return - EINVAL ;
1185
+
1186
+ if (!priv -> bitrate_const != !priv -> bitrate_const_cnt )
1187
+ return - EINVAL ;
1188
+
1189
+ if (!priv -> data_bitrate_const != !priv -> data_bitrate_const_cnt )
1190
+ return - EINVAL ;
1191
+
1076
1192
dev -> rtnl_link_ops = & can_link_ops ;
1077
1193
return register_netdev (dev );
1078
1194
}
0 commit comments