* [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.