Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
0003  * Copyright (C) 2006 Andrey Volkov, Varma Electronics
0004  * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
0005  */
0006 
0007 #include <linux/can/dev.h>
0008 
0009 /* Checks the validity of the specified bit-timing parameters prop_seg,
0010  * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate
0011  * prescaler value brp. You can find more information in the header
0012  * file linux/can/netlink.h.
0013  */
0014 static int can_fixup_bittiming(const struct net_device *dev, struct can_bittiming *bt,
0015                    const struct can_bittiming_const *btc)
0016 {
0017     const struct can_priv *priv = netdev_priv(dev);
0018     unsigned int tseg1, alltseg;
0019     u64 brp64;
0020 
0021     tseg1 = bt->prop_seg + bt->phase_seg1;
0022     if (!bt->sjw)
0023         bt->sjw = 1;
0024     if (bt->sjw > btc->sjw_max ||
0025         tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max ||
0026         bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max)
0027         return -ERANGE;
0028 
0029     brp64 = (u64)priv->clock.freq * (u64)bt->tq;
0030     if (btc->brp_inc > 1)
0031         do_div(brp64, btc->brp_inc);
0032     brp64 += 500000000UL - 1;
0033     do_div(brp64, 1000000000UL); /* the practicable BRP */
0034     if (btc->brp_inc > 1)
0035         brp64 *= btc->brp_inc;
0036     bt->brp = (u32)brp64;
0037 
0038     if (bt->brp < btc->brp_min || bt->brp > btc->brp_max)
0039         return -EINVAL;
0040 
0041     alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1;
0042     bt->bitrate = priv->clock.freq / (bt->brp * alltseg);
0043     bt->sample_point = ((tseg1 + 1) * 1000) / alltseg;
0044 
0045     return 0;
0046 }
0047 
0048 /* Checks the validity of predefined bitrate settings */
0049 static int
0050 can_validate_bitrate(const struct net_device *dev, const struct can_bittiming *bt,
0051              const u32 *bitrate_const,
0052              const unsigned int bitrate_const_cnt)
0053 {
0054     unsigned int i;
0055 
0056     for (i = 0; i < bitrate_const_cnt; i++) {
0057         if (bt->bitrate == bitrate_const[i])
0058             return 0;
0059     }
0060 
0061     return -EINVAL;
0062 }
0063 
0064 int can_get_bittiming(const struct net_device *dev, struct can_bittiming *bt,
0065               const struct can_bittiming_const *btc,
0066               const u32 *bitrate_const,
0067               const unsigned int bitrate_const_cnt)
0068 {
0069     int err;
0070 
0071     /* Depending on the given can_bittiming parameter structure the CAN
0072      * timing parameters are calculated based on the provided bitrate OR
0073      * alternatively the CAN timing parameters (tq, prop_seg, etc.) are
0074      * provided directly which are then checked and fixed up.
0075      */
0076     if (!bt->tq && bt->bitrate && btc)
0077         err = can_calc_bittiming(dev, bt, btc);
0078     else if (bt->tq && !bt->bitrate && btc)
0079         err = can_fixup_bittiming(dev, bt, btc);
0080     else if (!bt->tq && bt->bitrate && bitrate_const)
0081         err = can_validate_bitrate(dev, bt, bitrate_const,
0082                        bitrate_const_cnt);
0083     else
0084         err = -EINVAL;
0085 
0086     return err;
0087 }