All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC, PATCH v2] can: add CAN interface API for fixed bitrates
@ 2017-01-11 16:10 Marc Kleine-Budde
  2017-01-12  9:41 ` Kołłątaj, Remigiusz
  0 siblings, 1 reply; 4+ messages in thread
From: Marc Kleine-Budde @ 2017-01-11 16:10 UTC (permalink / raw)
  To: linux-can; +Cc: Marc Kleine-Budde

Inside the driver:
const u32 drvname_bitrate[] = { 20000, 50000, 100000 };

struct drvname_priv *priv;
priv = netdev_priv(dev);

priv->bitrate_const = drvname_bitrate;
priv->bitrate_const_cnt = ARRAY_SIZE(drvname_bitrate);

Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
Hello,

based on Remik's work. Rebased on the latest CAN termination API, streamlined
and add support for data_bitrate.

regards,
Marc

 drivers/net/can/dev.c            | 83 ++++++++++++++++++++++++++++++++--------
 include/linux/can/dev.h          |  4 ++
 include/uapi/linux/can/netlink.h |  2 +
 3 files changed, 73 insertions(+), 16 deletions(-)

diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 254183e5baf9..db6ad7f5d96d 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -279,8 +279,29 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
 	return 0;
 }
 
+/* Checks the validity of predefined bitrate settings */
+static int can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt,
+				const u32 *bitrate_const,
+				const int bitrate_const_cnt)
+{
+	struct can_priv *priv = netdev_priv(dev);
+	int i;
+
+	for (i = 0; i < bitrate_const_cnt; i++) {
+		if (bt->bitrate == bitrate_const[i])
+			break;
+	}
+
+	if (i >= priv->bitrate_const_cnt)
+		return -EINVAL;
+
+	return 0;
+}
+
 static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
-			     const struct can_bittiming_const *btc)
+			     const struct can_bittiming_const *btc,
+			     const u32 *bitrate_const,
+			     const int bitrate_const_cnt)
 {
 	int err;
 
@@ -290,10 +311,13 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
 	 * alternatively the CAN timing parameters (tq, prop_seg, etc.) are
 	 * provided directly which are then checked and fixed up.
 	 */
-	if (!bt->tq && bt->bitrate)
+	if (!bt->tq && bt->bitrate && btc)
 		err = can_calc_bittiming(dev, bt, btc);
-	else if (bt->tq && !bt->bitrate)
+	else if (bt->tq && !bt->bitrate && btc)
 		err = can_fixup_bittiming(dev, bt, btc);
+	else if (!bt->tq && bt->bitrate && bitrate_const)
+		err = can_validate_bitrate(dev, bt, bitrate_const,
+					   bitrate_const_cnt);
 	else
 		err = -EINVAL;
 
@@ -878,12 +902,12 @@ static int can_changelink(struct net_device *dev,
 			return -EOPNOTSUPP;
 
 		memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
-		if (priv->bittiming_const) {
-			err = can_get_bittiming(dev, &bt,
-						priv->bittiming_const);
-			if (err)
-				return err;
-		}
+		err = can_get_bittiming(dev, &bt,
+					priv->bittiming_const,
+					priv->bitrate_const,
+					priv->bitrate_const_cnt);
+		if (err)
+			return err;
 		memcpy(&priv->bittiming, &bt, sizeof(bt));
 
 		if (priv->do_set_bittiming) {
@@ -962,12 +986,12 @@ static int can_changelink(struct net_device *dev,
 
 		memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
 		       sizeof(dbt));
-		if (priv->data_bittiming_const) {
-			err = can_get_bittiming(dev, &dbt,
-						priv->data_bittiming_const);
-			if (err)
-				return err;
-		}
+		err = can_get_bittiming(dev, &dbt,
+					priv->data_bittiming_const,
+					priv->data_bitrate_const,
+					priv->data_bitrate_const_cnt);
+		if (err)
+			return err;
 		memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
 
 		if (priv->do_set_data_bittiming) {
@@ -1029,6 +1053,12 @@ static size_t can_get_size(const struct net_device *dev)
 		size += nla_total_size(sizeof(*priv->termination_const) *	/* IFLA_CAN_TERMINATION_CONST */
 				       priv->termination_const_cnt);
 	}
+	if (priv->bitrate_const)				/* IFLA_CAN_BITRATE_CONST */
+		size += nla_total_size(sizeof(*priv->bitrate_const) *
+				       priv->bitrate_const_cnt);
+	if (priv->data_bitrate_const)				/* IFLA_CAN_DATA_BITRATE_CONST */
+		size += nla_total_size(sizeof(*priv->data_bitrate_const) *
+				       priv->data_bitrate_const_cnt);
 
 	return size;
 }
@@ -1074,7 +1104,20 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
 	      nla_put(skb, IFLA_CAN_TERMINATION_CONST,
 		      sizeof(*priv->termination_const) *
 		      priv->termination_const_cnt,
-		      priv->termination_const))))
+		      priv->termination_const))) ||
+
+	    (priv->bitrate_const &&
+	     nla_put(skb, IFLA_CAN_BITRATE_CONST,
+		     sizeof(*priv->bitrate_const) *
+		     priv->bitrate_const_cnt,
+		     priv->bitrate_const)) ||
+
+	    (priv->data_bitrate_const &&
+	     nla_put(skb, IFLA_CAN_BITRATE_CONST,
+		     sizeof(*priv->data_bitrate_const) *
+		     priv->data_bitrate_const_cnt,
+		     priv->data_bitrate_const))
+	    )
 
 		return -EMSGSIZE;
 
@@ -1139,6 +1182,14 @@ int register_candev(struct net_device *dev)
 	    (!priv->termination_const && priv->termination_const_cnt != 0))
 		return -EINVAL;
 
+	if ((priv->bitrate_const && priv->bitrate_const_cnt <= 0) ||
+	    (!priv->bitrate_const && priv->bitrate_const_cnt != 0))
+		return -EINVAL;
+
+	if ((priv->data_bitrate_const && priv->data_bitrate_const_cnt <= 0) ||
+	    (!priv->data_bitrate_const && priv->data_bitrate_const_cnt != 0))
+		return -EINVAL;
+
 	dev->rtnl_link_ops = &can_link_ops;
 	return register_netdev(dev);
 }
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index cba7f4b5a722..02f5b789f79a 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -41,6 +41,10 @@ struct can_priv {
 	const u16 *termination_const;
 	const int termination_const_cnt;
 	u16 termination;
+	const u32 *bitrate_const;
+	const int bitrate_const_cnt;
+	const u32 *data_bitrate_const;
+	const int data_bitrate_const_cnt;
 	struct can_clock clock;
 
 	enum can_state state;
diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
index 7414771926fb..fdf75f74fdaf 100644
--- a/include/uapi/linux/can/netlink.h
+++ b/include/uapi/linux/can/netlink.h
@@ -129,6 +129,8 @@ enum {
 	IFLA_CAN_DATA_BITTIMING_CONST,
 	IFLA_CAN_TERMINATION,
 	IFLA_CAN_TERMINATION_CONST,
+	IFLA_CAN_BITRATE_CONST,
+	IFLA_CAN_DATA_BITRATE_CONST,
 	__IFLA_CAN_MAX
 };
 
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC, PATCH v2] can: add CAN interface API for fixed bitrates
  2017-01-11 16:10 [RFC, PATCH v2] can: add CAN interface API for fixed bitrates Marc Kleine-Budde
@ 2017-01-12  9:41 ` Kołłątaj, Remigiusz
  2017-01-12 16:36   ` Oliver Hartkopp
  0 siblings, 1 reply; 4+ messages in thread
From: Kołłątaj, Remigiusz @ 2017-01-12  9:41 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-can

Looks good to me.

Cheers,
Remik

On 11 January 2017 at 17:10, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> Inside the driver:
> const u32 drvname_bitrate[] = { 20000, 50000, 100000 };
>
> struct drvname_priv *priv;
> priv = netdev_priv(dev);
>
> priv->bitrate_const = drvname_bitrate;
> priv->bitrate_const_cnt = ARRAY_SIZE(drvname_bitrate);
>
> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
> ---
> Hello,
>
> based on Remik's work. Rebased on the latest CAN termination API, streamlined
> and add support for data_bitrate.
>
> regards,
> Marc
>
>  drivers/net/can/dev.c            | 83 ++++++++++++++++++++++++++++++++--------
>  include/linux/can/dev.h          |  4 ++
>  include/uapi/linux/can/netlink.h |  2 +
>  3 files changed, 73 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
> index 254183e5baf9..db6ad7f5d96d 100644
> --- a/drivers/net/can/dev.c
> +++ b/drivers/net/can/dev.c
> @@ -279,8 +279,29 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
>         return 0;
>  }
>
> +/* Checks the validity of predefined bitrate settings */
> +static int can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt,
> +                               const u32 *bitrate_const,
> +                               const int bitrate_const_cnt)
> +{
> +       struct can_priv *priv = netdev_priv(dev);
> +       int i;
> +
> +       for (i = 0; i < bitrate_const_cnt; i++) {
> +               if (bt->bitrate == bitrate_const[i])
> +                       break;
> +       }
> +
> +       if (i >= priv->bitrate_const_cnt)
> +               return -EINVAL;
> +
> +       return 0;
> +}
> +
>  static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
> -                            const struct can_bittiming_const *btc)
> +                            const struct can_bittiming_const *btc,
> +                            const u32 *bitrate_const,
> +                            const int bitrate_const_cnt)
>  {
>         int err;
>
> @@ -290,10 +311,13 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
>          * alternatively the CAN timing parameters (tq, prop_seg, etc.) are
>          * provided directly which are then checked and fixed up.
>          */
> -       if (!bt->tq && bt->bitrate)
> +       if (!bt->tq && bt->bitrate && btc)
>                 err = can_calc_bittiming(dev, bt, btc);
> -       else if (bt->tq && !bt->bitrate)
> +       else if (bt->tq && !bt->bitrate && btc)
>                 err = can_fixup_bittiming(dev, bt, btc);
> +       else if (!bt->tq && bt->bitrate && bitrate_const)
> +               err = can_validate_bitrate(dev, bt, bitrate_const,
> +                                          bitrate_const_cnt);
>         else
>                 err = -EINVAL;
>
> @@ -878,12 +902,12 @@ static int can_changelink(struct net_device *dev,
>                         return -EOPNOTSUPP;
>
>                 memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
> -               if (priv->bittiming_const) {
> -                       err = can_get_bittiming(dev, &bt,
> -                                               priv->bittiming_const);
> -                       if (err)
> -                               return err;
> -               }
> +               err = can_get_bittiming(dev, &bt,
> +                                       priv->bittiming_const,
> +                                       priv->bitrate_const,
> +                                       priv->bitrate_const_cnt);
> +               if (err)
> +                       return err;
>                 memcpy(&priv->bittiming, &bt, sizeof(bt));
>
>                 if (priv->do_set_bittiming) {
> @@ -962,12 +986,12 @@ static int can_changelink(struct net_device *dev,
>
>                 memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
>                        sizeof(dbt));
> -               if (priv->data_bittiming_const) {
> -                       err = can_get_bittiming(dev, &dbt,
> -                                               priv->data_bittiming_const);
> -                       if (err)
> -                               return err;
> -               }
> +               err = can_get_bittiming(dev, &dbt,
> +                                       priv->data_bittiming_const,
> +                                       priv->data_bitrate_const,
> +                                       priv->data_bitrate_const_cnt);
> +               if (err)
> +                       return err;
>                 memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
>
>                 if (priv->do_set_data_bittiming) {
> @@ -1029,6 +1053,12 @@ static size_t can_get_size(const struct net_device *dev)
>                 size += nla_total_size(sizeof(*priv->termination_const) *       /* IFLA_CAN_TERMINATION_CONST */
>                                        priv->termination_const_cnt);
>         }
> +       if (priv->bitrate_const)                                /* IFLA_CAN_BITRATE_CONST */
> +               size += nla_total_size(sizeof(*priv->bitrate_const) *
> +                                      priv->bitrate_const_cnt);
> +       if (priv->data_bitrate_const)                           /* IFLA_CAN_DATA_BITRATE_CONST */
> +               size += nla_total_size(sizeof(*priv->data_bitrate_const) *
> +                                      priv->data_bitrate_const_cnt);
>
>         return size;
>  }
> @@ -1074,7 +1104,20 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
>               nla_put(skb, IFLA_CAN_TERMINATION_CONST,
>                       sizeof(*priv->termination_const) *
>                       priv->termination_const_cnt,
> -                     priv->termination_const))))
> +                     priv->termination_const))) ||
> +
> +           (priv->bitrate_const &&
> +            nla_put(skb, IFLA_CAN_BITRATE_CONST,
> +                    sizeof(*priv->bitrate_const) *
> +                    priv->bitrate_const_cnt,
> +                    priv->bitrate_const)) ||
> +
> +           (priv->data_bitrate_const &&
> +            nla_put(skb, IFLA_CAN_BITRATE_CONST,
> +                    sizeof(*priv->data_bitrate_const) *
> +                    priv->data_bitrate_const_cnt,
> +                    priv->data_bitrate_const))
> +           )
>
>                 return -EMSGSIZE;
>
> @@ -1139,6 +1182,14 @@ int register_candev(struct net_device *dev)
>             (!priv->termination_const && priv->termination_const_cnt != 0))
>                 return -EINVAL;
>
> +       if ((priv->bitrate_const && priv->bitrate_const_cnt <= 0) ||
> +           (!priv->bitrate_const && priv->bitrate_const_cnt != 0))
> +               return -EINVAL;
> +
> +       if ((priv->data_bitrate_const && priv->data_bitrate_const_cnt <= 0) ||
> +           (!priv->data_bitrate_const && priv->data_bitrate_const_cnt != 0))
> +               return -EINVAL;
> +
>         dev->rtnl_link_ops = &can_link_ops;
>         return register_netdev(dev);
>  }
> diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
> index cba7f4b5a722..02f5b789f79a 100644
> --- a/include/linux/can/dev.h
> +++ b/include/linux/can/dev.h
> @@ -41,6 +41,10 @@ struct can_priv {
>         const u16 *termination_const;
>         const int termination_const_cnt;
>         u16 termination;
> +       const u32 *bitrate_const;
> +       const int bitrate_const_cnt;
> +       const u32 *data_bitrate_const;
> +       const int data_bitrate_const_cnt;
>         struct can_clock clock;
>
>         enum can_state state;
> diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
> index 7414771926fb..fdf75f74fdaf 100644
> --- a/include/uapi/linux/can/netlink.h
> +++ b/include/uapi/linux/can/netlink.h
> @@ -129,6 +129,8 @@ enum {
>         IFLA_CAN_DATA_BITTIMING_CONST,
>         IFLA_CAN_TERMINATION,
>         IFLA_CAN_TERMINATION_CONST,
> +       IFLA_CAN_BITRATE_CONST,
> +       IFLA_CAN_DATA_BITRATE_CONST,
>         __IFLA_CAN_MAX
>  };
>
> --
> 2.11.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC, PATCH v2] can: add CAN interface API for fixed bitrates
  2017-01-12  9:41 ` Kołłątaj, Remigiusz
@ 2017-01-12 16:36   ` Oliver Hartkopp
  2017-01-13 10:30     ` Marc Kleine-Budde
  0 siblings, 1 reply; 4+ messages in thread
From: Oliver Hartkopp @ 2017-01-12 16:36 UTC (permalink / raw)
  To: Kołłątaj, Remigiusz, Marc Kleine-Budde; +Cc: linux-can



On 01/12/2017 10:41 AM, Kołłątaj, Remigiusz wrote:
> Looks good to me.
>
> Cheers,
> Remik
>
> On 11 January 2017 at 17:10, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
>> Inside the driver:
>> const u32 drvname_bitrate[] = { 20000, 50000, 100000 };
>>
>> struct drvname_priv *priv;
>> priv = netdev_priv(dev);
>>
>> priv->bitrate_const = drvname_bitrate;
>> priv->bitrate_const_cnt = ARRAY_SIZE(drvname_bitrate);
>>
>> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
>> ---
>> Hello,
>>
>> based on Remik's work. Rebased on the latest CAN termination API, streamlined
>> and add support for data_bitrate.
>>
>> regards,
>> Marc
>>
>>  drivers/net/can/dev.c            | 83 ++++++++++++++++++++++++++++++++--------
>>  include/linux/can/dev.h          |  4 ++
>>  include/uapi/linux/can/netlink.h |  2 +
>>  3 files changed, 73 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
>> index 254183e5baf9..db6ad7f5d96d 100644
>> --- a/drivers/net/can/dev.c
>> +++ b/drivers/net/can/dev.c
>> @@ -279,8 +279,29 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
>>         return 0;
>>  }
>>
>> +/* Checks the validity of predefined bitrate settings */
>> +static int can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt,
>> +                               const u32 *bitrate_const,
>> +                               const int bitrate_const_cnt)
>> +{
>> +       struct can_priv *priv = netdev_priv(dev);
>> +       int i;
>> +
>> +       for (i = 0; i < bitrate_const_cnt; i++) {
>> +               if (bt->bitrate == bitrate_const[i])
>> +                       break;
>> +       }
>> +
>> +       if (i >= priv->bitrate_const_cnt)
>> +               return -EINVAL;
>> +
>> +       return 0;
>> +}
>> +
>>  static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
>> -                            const struct can_bittiming_const *btc)
>> +                            const struct can_bittiming_const *btc,
>> +                            const u32 *bitrate_const,
>> +                            const int bitrate_const_cnt)
>>  {
>>         int err;
>>
>> @@ -290,10 +311,13 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
>>          * alternatively the CAN timing parameters (tq, prop_seg, etc.) are
>>          * provided directly which are then checked and fixed up.
>>          */
>> -       if (!bt->tq && bt->bitrate)
>> +       if (!bt->tq && bt->bitrate && btc)
>>                 err = can_calc_bittiming(dev, bt, btc);
>> -       else if (bt->tq && !bt->bitrate)
>> +       else if (bt->tq && !bt->bitrate && btc)
>>                 err = can_fixup_bittiming(dev, bt, btc);
>> +       else if (!bt->tq && bt->bitrate && bitrate_const)
>> +               err = can_validate_bitrate(dev, bt, bitrate_const,
>> +                                          bitrate_const_cnt);
>>         else
>>                 err = -EINVAL;
>>
>> @@ -878,12 +902,12 @@ static int can_changelink(struct net_device *dev,
>>                         return -EOPNOTSUPP;
>>
>>                 memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
>> -               if (priv->bittiming_const) {
>> -                       err = can_get_bittiming(dev, &bt,
>> -                                               priv->bittiming_const);
>> -                       if (err)
>> -                               return err;
>> -               }
>> +               err = can_get_bittiming(dev, &bt,
>> +                                       priv->bittiming_const,
>> +                                       priv->bitrate_const,
>> +                                       priv->bitrate_const_cnt);
>> +               if (err)
>> +                       return err;
>>                 memcpy(&priv->bittiming, &bt, sizeof(bt));
>>
>>                 if (priv->do_set_bittiming) {
>> @@ -962,12 +986,12 @@ static int can_changelink(struct net_device *dev,
>>
>>                 memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
>>                        sizeof(dbt));
>> -               if (priv->data_bittiming_const) {
>> -                       err = can_get_bittiming(dev, &dbt,
>> -                                               priv->data_bittiming_const);
>> -                       if (err)
>> -                               return err;
>> -               }
>> +               err = can_get_bittiming(dev, &dbt,
>> +                                       priv->data_bittiming_const,
>> +                                       priv->data_bitrate_const,
>> +                                       priv->data_bitrate_const_cnt);
>> +               if (err)
>> +                       return err;
>>                 memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
>>
>>                 if (priv->do_set_data_bittiming) {
>> @@ -1029,6 +1053,12 @@ static size_t can_get_size(const struct net_device *dev)
>>                 size += nla_total_size(sizeof(*priv->termination_const) *       /* IFLA_CAN_TERMINATION_CONST */
>>                                        priv->termination_const_cnt);
>>         }
>> +       if (priv->bitrate_const)                                /* IFLA_CAN_BITRATE_CONST */
>> +               size += nla_total_size(sizeof(*priv->bitrate_const) *
>> +                                      priv->bitrate_const_cnt);
>> +       if (priv->data_bitrate_const)                           /* IFLA_CAN_DATA_BITRATE_CONST */
>> +               size += nla_total_size(sizeof(*priv->data_bitrate_const) *
>> +                                      priv->data_bitrate_const_cnt);
>>
>>         return size;
>>  }
>> @@ -1074,7 +1104,20 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
>>               nla_put(skb, IFLA_CAN_TERMINATION_CONST,
>>                       sizeof(*priv->termination_const) *
>>                       priv->termination_const_cnt,
>> -                     priv->termination_const))))
>> +                     priv->termination_const))) ||
>> +
>> +           (priv->bitrate_const &&
>> +            nla_put(skb, IFLA_CAN_BITRATE_CONST,
>> +                    sizeof(*priv->bitrate_const) *
>> +                    priv->bitrate_const_cnt,
>> +                    priv->bitrate_const)) ||
>> +
>> +           (priv->data_bitrate_const &&
>> +            nla_put(skb, IFLA_CAN_BITRATE_CONST,

copy/paste?

IFLA_CAN_DATA_BITRATE_CONST

>> +                    sizeof(*priv->data_bitrate_const) *
>> +                    priv->data_bitrate_const_cnt,
>> +                    priv->data_bitrate_const))
>> +           )
>>
>>                 return -EMSGSIZE;
>>
>> @@ -1139,6 +1182,14 @@ int register_candev(struct net_device *dev)
>>             (!priv->termination_const && priv->termination_const_cnt != 0))
>>                 return -EINVAL;
>>
>> +       if ((priv->bitrate_const && priv->bitrate_const_cnt <= 0) ||
>> +           (!priv->bitrate_const && priv->bitrate_const_cnt != 0))
>> +               return -EINVAL;
>> +
>> +       if ((priv->data_bitrate_const && priv->data_bitrate_const_cnt <= 0) ||
>> +           (!priv->data_bitrate_const && priv->data_bitrate_const_cnt != 0))
>> +               return -EINVAL;
>> +
>>         dev->rtnl_link_ops = &can_link_ops;
>>         return register_netdev(dev);
>>  }
>> diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
>> index cba7f4b5a722..02f5b789f79a 100644
>> --- a/include/linux/can/dev.h
>> +++ b/include/linux/can/dev.h
>> @@ -41,6 +41,10 @@ struct can_priv {
>>         const u16 *termination_const;
>>         const int termination_const_cnt;
>>         u16 termination;
>> +       const u32 *bitrate_const;
>> +       const int bitrate_const_cnt;
>> +       const u32 *data_bitrate_const;
>> +       const int data_bitrate_const_cnt;
>>         struct can_clock clock;
>>
>>         enum can_state state;
>> diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
>> index 7414771926fb..fdf75f74fdaf 100644
>> --- a/include/uapi/linux/can/netlink.h
>> +++ b/include/uapi/linux/can/netlink.h
>> @@ -129,6 +129,8 @@ enum {
>>         IFLA_CAN_DATA_BITTIMING_CONST,
>>         IFLA_CAN_TERMINATION,
>>         IFLA_CAN_TERMINATION_CONST,
>> +       IFLA_CAN_BITRATE_CONST,
>> +       IFLA_CAN_DATA_BITRATE_CONST,
>>         __IFLA_CAN_MAX
>>  };
>>
>> --
>> 2.11.0
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-can" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC, PATCH v2] can: add CAN interface API for fixed bitrates
  2017-01-12 16:36   ` Oliver Hartkopp
@ 2017-01-13 10:30     ` Marc Kleine-Budde
  0 siblings, 0 replies; 4+ messages in thread
From: Marc Kleine-Budde @ 2017-01-13 10:30 UTC (permalink / raw)
  To: Oliver Hartkopp, Kołłątaj, Remigiusz; +Cc: linux-can


[-- Attachment #1.1: Type: text/plain, Size: 7112 bytes --]

On 01/12/2017 05:36 PM, Oliver Hartkopp wrote:
> 
> 
> On 01/12/2017 10:41 AM, Kołłątaj, Remigiusz wrote:
>> Looks good to me.
>>
>> Cheers,
>> Remik
>>
>> On 11 January 2017 at 17:10, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
>>> Inside the driver:
>>> const u32 drvname_bitrate[] = { 20000, 50000, 100000 };
>>>
>>> struct drvname_priv *priv;
>>> priv = netdev_priv(dev);
>>>
>>> priv->bitrate_const = drvname_bitrate;
>>> priv->bitrate_const_cnt = ARRAY_SIZE(drvname_bitrate);
>>>
>>> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
>>> ---
>>> Hello,
>>>
>>> based on Remik's work. Rebased on the latest CAN termination API, streamlined
>>> and add support for data_bitrate.
>>>
>>> regards,
>>> Marc
>>>
>>>  drivers/net/can/dev.c            | 83 ++++++++++++++++++++++++++++++++--------
>>>  include/linux/can/dev.h          |  4 ++
>>>  include/uapi/linux/can/netlink.h |  2 +
>>>  3 files changed, 73 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
>>> index 254183e5baf9..db6ad7f5d96d 100644
>>> --- a/drivers/net/can/dev.c
>>> +++ b/drivers/net/can/dev.c
>>> @@ -279,8 +279,29 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
>>>         return 0;
>>>  }
>>>
>>> +/* Checks the validity of predefined bitrate settings */
>>> +static int can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt,
>>> +                               const u32 *bitrate_const,
>>> +                               const int bitrate_const_cnt)
>>> +{
>>> +       struct can_priv *priv = netdev_priv(dev);
>>> +       int i;
>>> +
>>> +       for (i = 0; i < bitrate_const_cnt; i++) {
>>> +               if (bt->bitrate == bitrate_const[i])
>>> +                       break;
>>> +       }
>>> +
>>> +       if (i >= priv->bitrate_const_cnt)
>>> +               return -EINVAL;
>>> +
>>> +       return 0;
>>> +}
>>> +
>>>  static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
>>> -                            const struct can_bittiming_const *btc)
>>> +                            const struct can_bittiming_const *btc,
>>> +                            const u32 *bitrate_const,
>>> +                            const int bitrate_const_cnt)
>>>  {
>>>         int err;
>>>
>>> @@ -290,10 +311,13 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
>>>          * alternatively the CAN timing parameters (tq, prop_seg, etc.) are
>>>          * provided directly which are then checked and fixed up.
>>>          */
>>> -       if (!bt->tq && bt->bitrate)
>>> +       if (!bt->tq && bt->bitrate && btc)
>>>                 err = can_calc_bittiming(dev, bt, btc);
>>> -       else if (bt->tq && !bt->bitrate)
>>> +       else if (bt->tq && !bt->bitrate && btc)
>>>                 err = can_fixup_bittiming(dev, bt, btc);
>>> +       else if (!bt->tq && bt->bitrate && bitrate_const)
>>> +               err = can_validate_bitrate(dev, bt, bitrate_const,
>>> +                                          bitrate_const_cnt);
>>>         else
>>>                 err = -EINVAL;
>>>
>>> @@ -878,12 +902,12 @@ static int can_changelink(struct net_device *dev,
>>>                         return -EOPNOTSUPP;
>>>
>>>                 memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
>>> -               if (priv->bittiming_const) {
>>> -                       err = can_get_bittiming(dev, &bt,
>>> -                                               priv->bittiming_const);
>>> -                       if (err)
>>> -                               return err;
>>> -               }
>>> +               err = can_get_bittiming(dev, &bt,
>>> +                                       priv->bittiming_const,
>>> +                                       priv->bitrate_const,
>>> +                                       priv->bitrate_const_cnt);
>>> +               if (err)
>>> +                       return err;
>>>                 memcpy(&priv->bittiming, &bt, sizeof(bt));
>>>
>>>                 if (priv->do_set_bittiming) {
>>> @@ -962,12 +986,12 @@ static int can_changelink(struct net_device *dev,
>>>
>>>                 memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
>>>                        sizeof(dbt));
>>> -               if (priv->data_bittiming_const) {
>>> -                       err = can_get_bittiming(dev, &dbt,
>>> -                                               priv->data_bittiming_const);
>>> -                       if (err)
>>> -                               return err;
>>> -               }
>>> +               err = can_get_bittiming(dev, &dbt,
>>> +                                       priv->data_bittiming_const,
>>> +                                       priv->data_bitrate_const,
>>> +                                       priv->data_bitrate_const_cnt);
>>> +               if (err)
>>> +                       return err;
>>>                 memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
>>>
>>>                 if (priv->do_set_data_bittiming) {
>>> @@ -1029,6 +1053,12 @@ static size_t can_get_size(const struct net_device *dev)
>>>                 size += nla_total_size(sizeof(*priv->termination_const) *       /* IFLA_CAN_TERMINATION_CONST */
>>>                                        priv->termination_const_cnt);
>>>         }
>>> +       if (priv->bitrate_const)                                /* IFLA_CAN_BITRATE_CONST */
>>> +               size += nla_total_size(sizeof(*priv->bitrate_const) *
>>> +                                      priv->bitrate_const_cnt);
>>> +       if (priv->data_bitrate_const)                           /* IFLA_CAN_DATA_BITRATE_CONST */
>>> +               size += nla_total_size(sizeof(*priv->data_bitrate_const) *
>>> +                                      priv->data_bitrate_const_cnt);
>>>
>>>         return size;
>>>  }
>>> @@ -1074,7 +1104,20 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
>>>               nla_put(skb, IFLA_CAN_TERMINATION_CONST,
>>>                       sizeof(*priv->termination_const) *
>>>                       priv->termination_const_cnt,
>>> -                     priv->termination_const))))
>>> +                     priv->termination_const))) ||
>>> +
>>> +           (priv->bitrate_const &&
>>> +            nla_put(skb, IFLA_CAN_BITRATE_CONST,
>>> +                    sizeof(*priv->bitrate_const) *
>>> +                    priv->bitrate_const_cnt,
>>> +                    priv->bitrate_const)) ||
>>> +
>>> +           (priv->data_bitrate_const &&
>>> +            nla_put(skb, IFLA_CAN_BITRATE_CONST,
> 
> copy/paste?
> 
> IFLA_CAN_DATA_BITRATE_CONST

Tnx.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-01-13 10:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-11 16:10 [RFC, PATCH v2] can: add CAN interface API for fixed bitrates Marc Kleine-Budde
2017-01-12  9:41 ` Kołłątaj, Remigiusz
2017-01-12 16:36   ` Oliver Hartkopp
2017-01-13 10:30     ` Marc Kleine-Budde

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.