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 */ 6 7 #include <linux/can/dev.h> 8 9 /* Checks the validity of the specified bit-timing parameters prop_seg, 10 * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate 11 * prescaler value brp. You can find more information in the header 12 * file linux/can/netlink.h. 13 */ 14 static int can_fixup_bittiming(const struct net_device *dev, struct can_bittiming *bt, 15 const struct can_bittiming_const *btc) 16 { 17 const struct can_priv *priv = netdev_priv(dev); 18 unsigned int tseg1, alltseg; 19 u64 brp64; 20 21 tseg1 = bt->prop_seg + bt->phase_seg1; 22 if (!bt->sjw) 23 bt->sjw = 1; 24 if (bt->sjw > btc->sjw_max || 25 tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max || 26 bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max) 27 return -ERANGE; 28 29 brp64 = (u64)priv->clock.freq * (u64)bt->tq; 30 if (btc->brp_inc > 1) 31 do_div(brp64, btc->brp_inc); 32 brp64 += 500000000UL - 1; 33 do_div(brp64, 1000000000UL); /* the practicable BRP */ 34 if (btc->brp_inc > 1) 35 brp64 *= btc->brp_inc; 36 bt->brp = (u32)brp64; 37 38 if (bt->brp < btc->brp_min || bt->brp > btc->brp_max) 39 return -EINVAL; 40 41 alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1; 42 bt->bitrate = priv->clock.freq / (bt->brp * alltseg); 43 bt->sample_point = ((tseg1 + 1) * 1000) / alltseg; 44 45 return 0; 46 } 47 48 /* Checks the validity of predefined bitrate settings */ 49 static int 50 can_validate_bitrate(const struct net_device *dev, const struct can_bittiming *bt, 51 const u32 *bitrate_const, 52 const unsigned int bitrate_const_cnt) 53 { 54 unsigned int i; 55 56 for (i = 0; i < bitrate_const_cnt; i++) { 57 if (bt->bitrate == bitrate_const[i]) 58 return 0; 59 } 60 61 return -EINVAL; 62 } 63 64 int can_get_bittiming(const struct net_device *dev, struct can_bittiming *bt, 65 const struct can_bittiming_const *btc, 66 const u32 *bitrate_const, 67 const unsigned int bitrate_const_cnt) 68 { 69 int err; 70 71 /* Depending on the given can_bittiming parameter structure the CAN 72 * timing parameters are calculated based on the provided bitrate OR 73 * alternatively the CAN timing parameters (tq, prop_seg, etc.) are 74 * provided directly which are then checked and fixed up. 75 */ 76 if (!bt->tq && bt->bitrate && btc) 77 err = can_calc_bittiming(dev, bt, btc); 78 else if (bt->tq && !bt->bitrate && btc) 79 err = can_fixup_bittiming(dev, bt, btc); 80 else if (!bt->tq && bt->bitrate && bitrate_const) 81 err = can_validate_bitrate(dev, bt, bitrate_const, 82 bitrate_const_cnt); 83 else 84 err = -EINVAL; 85 86 return err; 87 } 88