1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix 3 * Copyright (C) 2006 Andrey Volkov, Varma Electronics 4 * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com> 5 * Copyright (c) 2025 Vincent Mailhol <mailhol@kernel.org> 6 */ 7 8 #include <linux/can/dev.h> 9 10 void can_sjw_set_default(struct can_bittiming *bt) 11 { 12 if (bt->sjw) 13 return; 14 15 /* If user space provides no sjw, use sane default of phase_seg2 / 2 */ 16 bt->sjw = max(1U, min(bt->phase_seg1, bt->phase_seg2 / 2)); 17 } 18 19 int can_sjw_check(const struct net_device *dev, const struct can_bittiming *bt, 20 const struct can_bittiming_const *btc, struct netlink_ext_ack *extack) 21 { 22 if (bt->sjw > btc->sjw_max) { 23 NL_SET_ERR_MSG_FMT(extack, "sjw: %u greater than max sjw: %u", 24 bt->sjw, btc->sjw_max); 25 return -EINVAL; 26 } 27 28 if (bt->sjw > bt->phase_seg1) { 29 NL_SET_ERR_MSG_FMT(extack, 30 "sjw: %u greater than phase-seg1: %u", 31 bt->sjw, bt->phase_seg1); 32 return -EINVAL; 33 } 34 35 if (bt->sjw > bt->phase_seg2) { 36 NL_SET_ERR_MSG_FMT(extack, 37 "sjw: %u greater than phase-seg2: %u", 38 bt->sjw, bt->phase_seg2); 39 return -EINVAL; 40 } 41 42 return 0; 43 } 44 45 /* Checks the validity of the specified bit-timing parameters prop_seg, 46 * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate 47 * prescaler value brp. You can find more information in the header 48 * file linux/can/netlink.h. 49 */ 50 static int can_fixup_bittiming(const struct net_device *dev, struct can_bittiming *bt, 51 const struct can_bittiming_const *btc, 52 struct netlink_ext_ack *extack) 53 { 54 const unsigned int tseg1 = bt->prop_seg + bt->phase_seg1; 55 const struct can_priv *priv = netdev_priv(dev); 56 u64 brp64; 57 int err; 58 59 if (tseg1 < btc->tseg1_min) { 60 NL_SET_ERR_MSG_FMT(extack, "prop-seg + phase-seg1: %u less than tseg1-min: %u", 61 tseg1, btc->tseg1_min); 62 return -EINVAL; 63 } 64 if (tseg1 > btc->tseg1_max) { 65 NL_SET_ERR_MSG_FMT(extack, "prop-seg + phase-seg1: %u greater than tseg1-max: %u", 66 tseg1, btc->tseg1_max); 67 return -EINVAL; 68 } 69 if (bt->phase_seg2 < btc->tseg2_min) { 70 NL_SET_ERR_MSG_FMT(extack, "phase-seg2: %u less than tseg2-min: %u", 71 bt->phase_seg2, btc->tseg2_min); 72 return -EINVAL; 73 } 74 if (bt->phase_seg2 > btc->tseg2_max) { 75 NL_SET_ERR_MSG_FMT(extack, "phase-seg2: %u greater than tseg2-max: %u", 76 bt->phase_seg2, btc->tseg2_max); 77 return -EINVAL; 78 } 79 80 can_sjw_set_default(bt); 81 82 err = can_sjw_check(dev, bt, btc, extack); 83 if (err) 84 return err; 85 86 brp64 = (u64)priv->clock.freq * (u64)bt->tq; 87 if (btc->brp_inc > 1) 88 do_div(brp64, btc->brp_inc); 89 brp64 += 500000000UL - 1; 90 do_div(brp64, 1000000000UL); /* the practicable BRP */ 91 if (btc->brp_inc > 1) 92 brp64 *= btc->brp_inc; 93 bt->brp = (u32)brp64; 94 95 if (bt->brp < btc->brp_min) { 96 NL_SET_ERR_MSG_FMT(extack, "resulting brp: %u less than brp-min: %u", 97 bt->brp, btc->brp_min); 98 return -EINVAL; 99 } 100 if (bt->brp > btc->brp_max) { 101 NL_SET_ERR_MSG_FMT(extack, "resulting brp: %u greater than brp-max: %u", 102 bt->brp, btc->brp_max); 103 return -EINVAL; 104 } 105 106 bt->bitrate = priv->clock.freq / (bt->brp * can_bit_time(bt)); 107 bt->sample_point = ((CAN_SYNC_SEG + tseg1) * 1000) / can_bit_time(bt); 108 bt->tq = DIV_U64_ROUND_CLOSEST(mul_u32_u32(bt->brp, NSEC_PER_SEC), 109 priv->clock.freq); 110 111 return 0; 112 } 113 114 /* Checks the validity of predefined bitrate settings */ 115 static int 116 can_validate_bitrate(const struct net_device *dev, const struct can_bittiming *bt, 117 const u32 *bitrate_const, 118 const unsigned int bitrate_const_cnt, 119 struct netlink_ext_ack *extack) 120 { 121 unsigned int i; 122 123 for (i = 0; i < bitrate_const_cnt; i++) { 124 if (bt->bitrate == bitrate_const[i]) 125 return 0; 126 } 127 128 NL_SET_ERR_MSG_FMT(extack, "bitrate %u bps not supported", 129 bt->brp); 130 131 return -EINVAL; 132 } 133 134 int can_get_bittiming(const struct net_device *dev, struct can_bittiming *bt, 135 const struct can_bittiming_const *btc, 136 const u32 *bitrate_const, 137 const unsigned int bitrate_const_cnt, 138 struct netlink_ext_ack *extack) 139 { 140 /* Depending on the given can_bittiming parameter structure the CAN 141 * timing parameters are calculated based on the provided bitrate OR 142 * alternatively the CAN timing parameters (tq, prop_seg, etc.) are 143 * provided directly which are then checked and fixed up. 144 */ 145 if (!bt->tq && bt->bitrate && btc) 146 return can_calc_bittiming(dev, bt, btc, extack); 147 if (bt->tq && !bt->bitrate && btc) 148 return can_fixup_bittiming(dev, bt, btc, extack); 149 if (!bt->tq && bt->bitrate && bitrate_const) 150 return can_validate_bitrate(dev, bt, bitrate_const, 151 bitrate_const_cnt, extack); 152 153 return -EINVAL; 154 } 155 156 int can_validate_pwm_bittiming(const struct net_device *dev, 157 const struct can_pwm *pwm, 158 struct netlink_ext_ack *extack) 159 { 160 const struct can_priv *priv = netdev_priv(dev); 161 u32 xl_bit_time_tqmin = can_bit_time_tqmin(&priv->xl.data_bittiming); 162 u32 nom_bit_time_tqmin = can_bit_time_tqmin(&priv->bittiming); 163 u32 pwms_ns = can_tqmin_to_ns(pwm->pwms, priv->clock.freq); 164 u32 pwml_ns = can_tqmin_to_ns(pwm->pwml, priv->clock.freq); 165 166 if (pwms_ns + pwml_ns > CAN_PWM_NS_MAX) { 167 NL_SET_ERR_MSG_FMT(extack, 168 "The PWM symbol duration: %u ns may not exceed %u ns", 169 pwms_ns + pwml_ns, CAN_PWM_NS_MAX); 170 return -EINVAL; 171 } 172 173 if (pwms_ns < CAN_PWM_DECODE_NS) { 174 NL_SET_ERR_MSG_FMT(extack, 175 "PWMS: %u ns shall be at least %u ns", 176 pwms_ns, CAN_PWM_DECODE_NS); 177 return -EINVAL; 178 } 179 180 if (pwm->pwms >= pwm->pwml) { 181 NL_SET_ERR_MSG_FMT(extack, 182 "PWMS: %u tqmin shall be smaller than PWML: %u tqmin", 183 pwm->pwms, pwm->pwml); 184 return -EINVAL; 185 } 186 187 if (pwml_ns - pwms_ns < 2 * CAN_PWM_DECODE_NS) { 188 NL_SET_ERR_MSG_FMT(extack, 189 "At least %u ns shall separate PWMS: %u ns from PMWL: %u ns", 190 2 * CAN_PWM_DECODE_NS, pwms_ns, pwml_ns); 191 return -EINVAL; 192 } 193 194 if (xl_bit_time_tqmin % (pwm->pwms + pwm->pwml) != 0) { 195 NL_SET_ERR_MSG_FMT(extack, 196 "PWM duration: %u tqmin does not divide XL's bit time: %u tqmin", 197 pwm->pwms + pwm->pwml, xl_bit_time_tqmin); 198 return -EINVAL; 199 } 200 201 if (pwm->pwmo >= pwm->pwms + pwm->pwml) { 202 NL_SET_ERR_MSG_FMT(extack, 203 "PWMO: %u tqmin can not be greater than PWMS + PWML: %u tqmin", 204 pwm->pwmo, pwm->pwms + pwm->pwml); 205 return -EINVAL; 206 } 207 208 if (nom_bit_time_tqmin % (pwm->pwms + pwm->pwml) != pwm->pwmo) { 209 NL_SET_ERR_MSG_FMT(extack, 210 "Can not assemble nominal bit time: %u tqmin out of PWMS + PMWL and PWMO", 211 nom_bit_time_tqmin); 212 return -EINVAL; 213 } 214 215 return 0; 216 } 217