[RFC PATCH] can: dev: Add check for the minimum value of a bit time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As ISO 11898-1 said: The total number of time quanta in a nominal bit
time shall be programmable at least from 8 to 25 for implementation that
are not FD enabled. For implementations that are FD enabled, the total
number of time quanta in a data bit time shall be programmable at least
from 5 to 25 and in a nominal bit time at least from 8 to 80.

So the minimum value for nominal bit time is 8 and for data bit time is
5, had better ensure the minimum value of a bit time.

Signed-off-by: Joakim Zhang <qiangqing.zhang@xxxxxxx>
---
 drivers/net/can/dev.c | 37 +++++++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index ac86be52b461..69e693c79579 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -115,7 +115,8 @@ can_update_sample_point(const struct can_bittiming_const *btc,
 	return best_sample_point;
 }
 
-static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
+static int can_calc_bittiming(struct net_device *dev, bool is_data_bt,
+			      struct can_bittiming *bt,
 			      const struct can_bittiming_const *btc)
 {
 	struct can_priv *priv = netdev_priv(dev);
@@ -147,6 +148,14 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
 	     tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) {
 		tsegall = CAN_CALC_SYNC_SEG + tseg / 2;
 
+		/* the total number of time quanta in a data bit time
+		 * (SYNC_SEG + TSEG1 + TSEG2) shall be programmable at least 5.
+		 * the total number of time quanta in a nominal bit time
+		 * (SYNC_SEG + TSEG1 + TSEG2) shall be programmable at least 8.
+		 */
+		if ((is_data_bt && tsegall < 5) || (!is_data_bt && tsegall < 8))
+			continue;
+
 		/* Compute all possible tseg choices (tseg=tseg1+tseg2) */
 		brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2;
 
@@ -228,7 +237,8 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
 	return 0;
 }
 #else /* !CONFIG_CAN_CALC_BITTIMING */
-static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
+static int can_calc_bittiming(struct net_device *dev, bool is_data_bt,
+			      struct can_bittiming *bt,
 			      const struct can_bittiming_const *btc)
 {
 	netdev_err(dev, "bit-timing calculation not available\n");
@@ -241,7 +251,8 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
  * prescaler value brp. You can find more information in the header
  * file linux/can/netlink.h.
  */
-static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
+static int can_fixup_bittiming(struct net_device *dev, bool is_data_bt,
+			       struct can_bittiming *bt,
 			       const struct can_bittiming_const *btc)
 {
 	struct can_priv *priv = netdev_priv(dev);
@@ -269,6 +280,15 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
 		return -EINVAL;
 
 	alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1;
+
+	/* the total number of time quanta in a data bit time
+	 * (SYNC_SEG + TSEG1 + TSEG2) shall be programmable at least 5.
+	 * the total number of time quanta in a nominal bit time
+	 * (SYNC_SEG + TSEG1 + TSEG2) shall be programmable at least 8.
+	 */
+	if ((is_data_bt && alltseg < 5) || (!is_data_bt && alltseg < 8))
+		return -EINVAL;
+
 	bt->bitrate = priv->clock.freq / (bt->brp * alltseg);
 	bt->sample_point = ((tseg1 + 1) * 1000) / alltseg;
 
@@ -295,7 +315,8 @@ can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt,
 	return 0;
 }
 
-static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
+static int can_get_bittiming(struct net_device *dev, bool is_data_bt,
+			     struct can_bittiming *bt,
 			     const struct can_bittiming_const *btc,
 			     const u32 *bitrate_const,
 			     const unsigned int bitrate_const_cnt)
@@ -308,9 +329,9 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
 	 * provided directly which are then checked and fixed up.
 	 */
 	if (!bt->tq && bt->bitrate && btc)
-		err = can_calc_bittiming(dev, bt, btc);
+		err = can_calc_bittiming(dev, is_data_bt, bt, btc);
 	else if (bt->tq && !bt->bitrate && btc)
-		err = can_fixup_bittiming(dev, bt, btc);
+		err = can_fixup_bittiming(dev, is_data_bt, bt, btc);
 	else if (!bt->tq && bt->bitrate && bitrate_const)
 		err = can_validate_bitrate(dev, bt, bitrate_const,
 					   bitrate_const_cnt);
@@ -944,7 +965,7 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
 			return -EOPNOTSUPP;
 
 		memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
-		err = can_get_bittiming(dev, &bt,
+		err = can_get_bittiming(dev, false, &bt,
 					priv->bittiming_const,
 					priv->bitrate_const,
 					priv->bitrate_const_cnt);
@@ -1035,7 +1056,7 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
 
 		memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
 		       sizeof(dbt));
-		err = can_get_bittiming(dev, &dbt,
+		err = can_get_bittiming(dev, true, &dbt,
 					priv->data_bittiming_const,
 					priv->data_bitrate_const,
 					priv->data_bitrate_const_cnt);
-- 
2.17.1





[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux