Re: [PATCH v4 10/11] can: lin: Support setting LIN mode
From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Date: 2024-05-10 14:39:27
Also in:
linux-can, linux-devicetree, linux-input, linux-serial
On Thu, 9 May 2024, Christoph Fritz wrote:
quoted hunk ↗ jump to hunk
A LIN node can work as commander or responder, so introduce a new control mode (CAN_CTRLMODE_LIN_COMMANDER) for configuration. This enables e.g. the userland tool ip from iproute2 to turn on commander mode when the device is being brought up. Signed-off-by: Christoph Fritz <redacted> --- drivers/net/can/lin.c | 40 +++++++++++++++++++++++++++++++- include/net/lin.h | 7 ++++++ include/uapi/linux/can/netlink.h | 1 + 3 files changed, 47 insertions(+), 1 deletion(-)diff --git a/drivers/net/can/lin.c b/drivers/net/can/lin.c index f77abd7d7d21c..03ddf5d5a31b8 100644 --- a/drivers/net/can/lin.c +++ b/drivers/net/can/lin.c@@ -262,11 +262,40 @@ static netdev_tx_t lin_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } +static int lin_update_mode(struct net_device *ndev) +{ + struct lin_device *ldev = netdev_priv(ndev); + u32 ctrlmode = ldev->can.ctrlmode; + enum lin_mode lm; + int ret = 0; + + lm = (ctrlmode & CAN_CTRLMODE_LIN_COMMANDER) ? LINBUS_COMMANDER : + LINBUS_RESPONDER; + if (ldev->lmode != lm) { + if (!ldev->ldev_ops->update_lin_mode) { + netdev_err(ndev, "setting lin mode unsupported\n");
In user visible messages, it would be best to use the expected capitalization, which I suppose is LIN given you use capitals in the commit message yourself?
+ return -EINVAL;
+ }
+ ret = ldev->ldev_ops->update_lin_mode(ldev, lm);
+ if (ret) {
+ netdev_err(ndev, "Failed to set lin mode: %d\n", ret);Ditto. There might be other cases in any of the patches, please check.
quoted hunk ↗ jump to hunk
+ return ret; + } + ldev->lmode = lm; + } + + return ret; +} + static int lin_open(struct net_device *ndev) { struct lin_device *ldev = netdev_priv(ndev); int ret; + ret = lin_update_mode(ndev); + if (ret) + return ret; + ldev->tx_busy = false; ret = open_candev(ndev);@@ -443,7 +472,7 @@ struct lin_device *register_lin(struct device *dev, ndev->sysfs_groups[0] = &lin_sysfs_group; ldev->can.bittiming.bitrate = LIN_DEFAULT_BAUDRATE; ldev->can.ctrlmode = CAN_CTRLMODE_LIN; - ldev->can.ctrlmode_supported = 0; + ldev->can.ctrlmode_supported = CAN_CTRLMODE_LIN_COMMANDER; ldev->can.bitrate_const = lin_bitrate; ldev->can.bitrate_const_cnt = ARRAY_SIZE(lin_bitrate); ldev->can.do_set_bittiming = lin_set_bittiming;@@ -458,6 +487,15 @@ struct lin_device *register_lin(struct device *dev, goto exit_candev; } + ldev->lmode = LINBUS_RESPONDER; + if (ldev->ldev_ops->update_lin_mode) { + ret = ldev->ldev_ops->update_lin_mode(ldev, ldev->lmode); + if (ret) { + netdev_err(ndev, "updating lin mode failed\n");
Ditto.
quoted hunk ↗ jump to hunk
+ goto exit_candev; + } + } + ret = register_candev(ndev); if (ret) goto exit_candev;diff --git a/include/net/lin.h b/include/net/lin.h index 31bb0feefd188..63ac870a0ab6f 100644 --- a/include/net/lin.h +++ b/include/net/lin.h@@ -36,6 +36,11 @@ struct lin_attr { struct lin_device *ldev; }; +enum lin_mode { + LINBUS_RESPONDER = 0, + LINBUS_COMMANDER, +}; + struct lin_device { struct can_priv can; /* must be the first member */ struct net_device *ndev;@@ -45,6 +50,7 @@ struct lin_device { struct work_struct tx_work; bool tx_busy; struct sk_buff *tx_skb; + enum lin_mode lmode; }; enum lin_checksum_mode {@@ -71,6 +77,7 @@ struct lin_device_ops { int (*ldo_open)(struct lin_device *ldev); int (*ldo_stop)(struct lin_device *ldev); int (*ldo_tx)(struct lin_device *ldev, const struct lin_frame *frame); + int (*update_lin_mode)(struct lin_device *ldev, enum lin_mode lm); int (*update_bitrate)(struct lin_device *ldev, u16 bitrate); int (*update_responder_answer)(struct lin_device *ldev, const struct lin_responder_answer *answ);diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h index a37f56d86c5f2..cc390f6444d59 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h@@ -104,6 +104,7 @@ struct can_ctrlmode { #define CAN_CTRLMODE_TDC_AUTO 0x200 /* CAN transiver automatically calculates TDCV */ #define CAN_CTRLMODE_TDC_MANUAL 0x400 /* TDCV is manually set up by user */ #define CAN_CTRLMODE_LIN BIT(11) /* LIN bus mode */ +#define CAN_CTRLMODE_LIN_COMMANDER BIT(12) /* LIN bus specific commander mode */ /* * CAN device statistics
-- i.