linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute
@ 2022-08-01  8:04 Lukas Magel
  2022-08-01 14:36 ` Vincent MAILHOL
                   ` (13 more replies)
  0 siblings, 14 replies; 48+ messages in thread
From: Lukas Magel @ 2022-08-01  8:04 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel, Vincent Mailhol

Peak USB devices support a configurable u8 / u32 device ID. In
multi-device setups, this device ID can be configured and used to
identify individual CAN interfaces independent of the order in which
they are plugged into the system. At the current time, the device ID
is already queried from the device and stored in the peak_usb_device
struct.

This patch exports the device ID (called device_number in the struct)
as a sysfs attribute. The attribute name was chosen to be device_id
instead of device_number because the latter has been deprecated by Peak
in their API.

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
For the moment, the patch only implements read support for the device
ID. My next goal is to also implement write access. However, this
will require a more significant modification of the driver since the
corresponding commands for ID retrieval and configuration are not
implemented for all device types.

 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 27b0a72fd885..43df178e9473 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -15,6 +15,8 @@
 #include <linux/netdevice.h>
 #include <linux/usb.h>
 #include <linux/ethtool.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -53,6 +55,15 @@ static const struct usb_device_id peak_usb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, peak_usb_table);
 
+static ssize_t device_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct net_device *netdev = to_net_dev(dev);
+	struct peak_usb_device *peak_dev = netdev_priv(netdev);
+
+	return sysfs_emit(buf, "%08X\n", peak_dev->device_number);
+}
+static DEVICE_ATTR_RO(device_id);
+
 /*
  * dump memory
  */
@@ -887,6 +898,11 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
 			peak_usb_adapter->name, ctrl_idx, dev->device_number);
 
+	err = device_create_file(&netdev->dev, &dev_attr_device_id);
+	/* Do not error out since device was configured successfully */
+	if (err)
+		netdev_warn(netdev, "unable to expose device_id via sysfs %d\n", err);
+
 	return 0;
 
 adap_dev_free:
@@ -923,6 +939,8 @@ static void peak_usb_disconnect(struct usb_interface *intf)
 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
 		strlcpy(name, netdev->name, IFNAMSIZ);
 
+		device_remove_file(&netdev->dev, &dev_attr_device_id);
+
 		unregister_netdev(netdev);
 
 		kfree(dev->cmd_buf);
-- 
2.37.1


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

* Re: [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
@ 2022-08-01 14:36 ` Vincent MAILHOL
  2022-08-02 19:26   ` [PATCH v2] " Lukas Magel
  2022-09-15  9:54 ` [RESEND PATCH " Lukas Magel
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 48+ messages in thread
From: Vincent MAILHOL @ 2022-08-01 14:36 UTC (permalink / raw)
  To: Lukas Magel; +Cc: linux-can

Hi Lukas,

Welcome on the linux-can mailing list!

On Mon. 1 août 2022 at 17:13, Lukas Magel <lukas.magel@posteo.net> wrote:
> Peak USB devices support a configurable u8 / u32 device ID. In
> multi-device setups, this device ID can be configured and used to
> identify individual CAN interfaces independent of the order in which
> they are plugged into the system. At the current time, the device ID
> is already queried from the device and stored in the peak_usb_device
> struct.
>
> This patch exports the device ID (called device_number in the struct)
> as a sysfs attribute. The attribute name was chosen to be device_id
> instead of device_number because the latter has been deprecated by Peak
> in their API.
>
> Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
> Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>

For the public record, I did the review in private message.

> ---
> For the moment, the patch only implements read support for the device
> ID. My next goal is to also implement write access. However, this
> will require a more significant modification of the driver since the
> corresponding commands for ID retrieval and configuration are not
> implemented for all device types.
>
>  drivers/net/can/usb/peak_usb/pcan_usb_core.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> index 27b0a72fd885..43df178e9473 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> @@ -15,6 +15,8 @@
>  #include <linux/netdevice.h>
>  #include <linux/usb.h>
>  #include <linux/ethtool.h>
> +#include <linux/device.h>
> +#include <linux/sysfs.h>
>
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
> @@ -53,6 +55,15 @@ static const struct usb_device_id peak_usb_table[] = {
>
>  MODULE_DEVICE_TABLE(usb, peak_usb_table);
>
> +static ssize_t device_id_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +       struct net_device *netdev = to_net_dev(dev);
> +       struct peak_usb_device *peak_dev = netdev_priv(netdev);
> +
> +       return sysfs_emit(buf, "%08X\n", peak_dev->device_number);
> +}
> +static DEVICE_ATTR_RO(device_id);
> +
>  /*
>   * dump memory
>   */
> @@ -887,6 +898,11 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
>         netdev_info(netdev, "attached to %s channel %u (device %u)\n",
>                         peak_usb_adapter->name, ctrl_idx, dev->device_number);
>
> +       err = device_create_file(&netdev->dev, &dev_attr_device_id);
> +       /* Do not error out since device was configured successfully */
> +       if (err)
> +               netdev_warn(netdev, "unable to expose device_id via sysfs %d\n", err);

netdev_warn(netdev, "unable to expose device_id via sysfs %pe\n", ERR_PTR(err));

I forgot this point in my first review. The %pe will print the
mnemotechnic instead of the error number. c.f.:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=57f5677e535ba24b8926a7125be2ef8d7f09323c

> +
>         return 0;
>
>  adap_dev_free:
> @@ -923,6 +939,8 @@ static void peak_usb_disconnect(struct usb_interface *intf)
>                 dev->state &= ~PCAN_USB_STATE_CONNECTED;
>                 strlcpy(name, netdev->name, IFNAMSIZ);
>
> +               device_remove_file(&netdev->dev, &dev_attr_device_id);
> +
>                 unregister_netdev(netdev);
>
>                 kfree(dev->cmd_buf);
> --
> 2.37.1
>

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

* [PATCH v2] can: peak_usb: export PCAN device ID as sysfs device attribute
  2022-08-01 14:36 ` Vincent MAILHOL
@ 2022-08-02 19:26   ` Lukas Magel
  0 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-08-02 19:26 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel, Vincent Mailhol

Peak USB devices support a configurable u8 / u32 device ID. In
multi-device setups, this device ID can be configured and used to
identify individual CAN interfaces independent of the order in which
they are plugged into the system. At the current time, the device ID
is already queried from the device and stored in the peak_usb_device
struct.

This patch exports the device ID (called device_number in the struct)
as a sysfs attribute. The attribute name was chosen to be device_id
instead of device_number because the latter has been deprecated by Peak
in their API.

V2: Update netdev_warn to output the mnemonic of the error value

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
---
Thank you Vincent for the feedback. I updated the netdev_warn
accordingly.

 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 27b0a72fd885..7af3dd0a1b35 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -15,6 +15,8 @@
 #include <linux/netdevice.h>
 #include <linux/usb.h>
 #include <linux/ethtool.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -53,6 +55,15 @@ static const struct usb_device_id peak_usb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, peak_usb_table);
 
+static ssize_t device_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct net_device *netdev = to_net_dev(dev);
+	struct peak_usb_device *peak_dev = netdev_priv(netdev);
+
+	return sysfs_emit(buf, "%08X\n", peak_dev->device_number);
+}
+static DEVICE_ATTR_RO(device_id);
+
 /*
  * dump memory
  */
@@ -887,6 +898,11 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
 			peak_usb_adapter->name, ctrl_idx, dev->device_number);
 
+	err = device_create_file(&netdev->dev, &dev_attr_device_id);
+	/* Do not error out since device was configured successfully */
+	if (err)
+		netdev_warn(netdev, "unable to expose device_id via sysfs: %pe\n", ERR_PTR(err));
+
 	return 0;
 
 adap_dev_free:
@@ -923,6 +939,8 @@ static void peak_usb_disconnect(struct usb_interface *intf)
 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
 		strlcpy(name, netdev->name, IFNAMSIZ);
 
+		device_remove_file(&netdev->dev, &dev_attr_device_id);
+
 		unregister_netdev(netdev);
 
 		kfree(dev->cmd_buf);
-- 
2.37.1


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

* [RESEND PATCH v2] can: peak_usb: export PCAN device ID as sysfs device attribute
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
  2022-08-01 14:36 ` Vincent MAILHOL
@ 2022-09-15  9:54 ` Lukas Magel
  2022-09-28 20:43   ` Lukas Magel
  2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 48+ messages in thread
From: Lukas Magel @ 2022-09-15  9:54 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel, Vincent Mailhol, Stephane Grosjean

Peak USB devices support a configurable u8 / u32 device ID. In
multi-device setups, this device ID can be configured and used to
identify individual CAN interfaces independent of the order in which
they are plugged into the system. At the current time, the device ID
is already queried from the device and stored in the peak_usb_device
struct.

This patch exports the device ID (called device_number in the struct)
as a sysfs attribute. The attribute name was chosen to be device_id
instead of device_number because the latter has been deprecated by Peak
in their API.

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
CC: Stephane Grosjean <s.grosjean@peak-system.com>
---
V2: Update netdev_warn to output the mnemonic of the error value

Resubmission of the patch. Also added Stéphane as maintainer in CC.

 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 27b0a72fd885..7af3dd0a1b35 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -15,6 +15,8 @@
 #include <linux/netdevice.h>
 #include <linux/usb.h>
 #include <linux/ethtool.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -53,6 +55,15 @@ static const struct usb_device_id peak_usb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, peak_usb_table);
 
+static ssize_t device_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct net_device *netdev = to_net_dev(dev);
+	struct peak_usb_device *peak_dev = netdev_priv(netdev);
+
+	return sysfs_emit(buf, "%08X\n", peak_dev->device_number);
+}
+static DEVICE_ATTR_RO(device_id);
+
 /*
  * dump memory
  */
@@ -887,6 +898,11 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
 			peak_usb_adapter->name, ctrl_idx, dev->device_number);
 
+	err = device_create_file(&netdev->dev, &dev_attr_device_id);
+	/* Do not error out since device was configured successfully */
+	if (err)
+		netdev_warn(netdev, "unable to expose device_id via sysfs: %pe\n", ERR_PTR(err));
+
 	return 0;
 
 adap_dev_free:
@@ -923,6 +939,8 @@ static void peak_usb_disconnect(struct usb_interface *intf)
 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
 		strlcpy(name, netdev->name, IFNAMSIZ);
 
+		device_remove_file(&netdev->dev, &dev_attr_device_id);
+
 		unregister_netdev(netdev);
 
 		kfree(dev->cmd_buf);
-- 
2.37.1


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

* Re: [RESEND PATCH v2] can: peak_usb: export PCAN device ID as sysfs device attribute
  2022-09-15  9:54 ` [RESEND PATCH " Lukas Magel
@ 2022-09-28 20:43   ` Lukas Magel
  2022-09-30 12:06     ` Marc Kleine-Budde
  0 siblings, 1 reply; 48+ messages in thread
From: Lukas Magel @ 2022-09-28 20:43 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: Stephane Grosjean, linux-can

Hello Marc,

I was made aware by Stéphane that there has previously been discussion about
registering a sysfs file for reading and writing the device ID [1]. IMHO, I
believe the sysfs file approach would have one important advantage over using
ethtool: udev rule matching.

I often work with setups that feature several CAN interfaces. In such a setup, I
want to assign persistent interface names via udev in case device probing is not
deterministic or the devices are plugged in to different ports. At the moment,
the PEAK device driver and the underlying USB interface do not export any
practically usable identifier for discriminating between different interfaces of
the same type. The device ID solves this problem since it can be configured per
CAN interface to uniquely identify the interface. If the device ID is exported
as sysfs file, it is directly available for matching in udev rules via the
ATTR{...} key. This would solve the CAN interface identification problem and
allow easy read and write access to the device ID without Windows userspace tools.

Regards,
Lukas

[1]
https://lore.kernel.org/linux-can/20211117150132.37056-1-s.grosjean@peak-system.com/

On 15.09.22 11:54, Lukas Magel wrote:
> Peak USB devices support a configurable u8 / u32 device ID. In
> multi-device setups, this device ID can be configured and used to
> identify individual CAN interfaces independent of the order in which
> they are plugged into the system. At the current time, the device ID
> is already queried from the device and stored in the peak_usb_device
> struct.
>
> This patch exports the device ID (called device_number in the struct)
> as a sysfs attribute. The attribute name was chosen to be device_id
> instead of device_number because the latter has been deprecated by Peak
> in their API.
>
> Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
> Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> CC: Stephane Grosjean <s.grosjean@peak-system.com>
> ---
> V2: Update netdev_warn to output the mnemonic of the error value
>
> Resubmission of the patch. Also added Stéphane as maintainer in CC.
>
>  drivers/net/can/usb/peak_usb/pcan_usb_core.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> index 27b0a72fd885..7af3dd0a1b35 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> @@ -15,6 +15,8 @@
>  #include <linux/netdevice.h>
>  #include <linux/usb.h>
>  #include <linux/ethtool.h>
> +#include <linux/device.h>
> +#include <linux/sysfs.h>
>  
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
> @@ -53,6 +55,15 @@ static const struct usb_device_id peak_usb_table[] = {
>  
>  MODULE_DEVICE_TABLE(usb, peak_usb_table);
>  
> +static ssize_t device_id_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +	struct net_device *netdev = to_net_dev(dev);
> +	struct peak_usb_device *peak_dev = netdev_priv(netdev);
> +
> +	return sysfs_emit(buf, "%08X\n", peak_dev->device_number);
> +}
> +static DEVICE_ATTR_RO(device_id);
> +
>  /*
>   * dump memory
>   */
> @@ -887,6 +898,11 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
>  	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
>  			peak_usb_adapter->name, ctrl_idx, dev->device_number);
>  
> +	err = device_create_file(&netdev->dev, &dev_attr_device_id);
> +	/* Do not error out since device was configured successfully */
> +	if (err)
> +		netdev_warn(netdev, "unable to expose device_id via sysfs: %pe\n", ERR_PTR(err));
> +
>  	return 0;
>  
>  adap_dev_free:
> @@ -923,6 +939,8 @@ static void peak_usb_disconnect(struct usb_interface *intf)
>  		dev->state &= ~PCAN_USB_STATE_CONNECTED;
>  		strlcpy(name, netdev->name, IFNAMSIZ);
>  
> +		device_remove_file(&netdev->dev, &dev_attr_device_id);
> +
>  		unregister_netdev(netdev);
>  
>  		kfree(dev->cmd_buf);

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

* Re: [RESEND PATCH v2] can: peak_usb: export PCAN device ID as sysfs device attribute
  2022-09-28 20:43   ` Lukas Magel
@ 2022-09-30 12:06     ` Marc Kleine-Budde
  2022-09-30 14:20       ` Marc Kleine-Budde
  0 siblings, 1 reply; 48+ messages in thread
From: Marc Kleine-Budde @ 2022-09-30 12:06 UTC (permalink / raw)
  To: Lukas Magel; +Cc: Stephane Grosjean, linux-can

[-- Attachment #1: Type: text/plain, Size: 5099 bytes --]

On 28.09.2022 20:43:19, Lukas Magel wrote:
> I was made aware by Stéphane that there has previously been discussion about
> registering a sysfs file for reading and writing the device ID [1]. IMHO, I
> believe the sysfs file approach would have one important advantage over using
> ethtool: udev rule matching.
> 
> I often work with setups that feature several CAN interfaces. In such a setup, I
> want to assign persistent interface names via udev in case device probing is not
> deterministic or the devices are plugged in to different ports. At the moment,
> the PEAK device driver and the underlying USB interface do not export any
> practically usable identifier for discriminating between different interfaces of
> the same type. The device ID solves this problem since it can be configured per
> CAN interface to uniquely identify the interface. If the device ID is exported
> as sysfs file, it is directly available for matching in udev rules via the
> ATTR{...} key. This would solve the CAN interface identification problem and
> allow easy read and write access to the device ID without Windows userspace tools.

I'm fine with a RO sysfs attribute. For writing the ethtool interface
should be used instead.

Please document the sysfs entry in
Documentation/ABI/testing/sysfs-class-net-FOO, with foo according to
/sys/class/net/<iface>/FOO, see
"Documentation/ABI/testing/sysfs-class-net-grcan" as an example.

> Regards,
> Lukas
> 
> [1]
> https://lore.kernel.org/linux-can/20211117150132.37056-1-s.grosjean@peak-system.com/
> 
> On 15.09.22 11:54, Lukas Magel wrote:
> > Peak USB devices support a configurable u8 / u32 device ID. In
> > multi-device setups, this device ID can be configured and used to
> > identify individual CAN interfaces independent of the order in which
> > they are plugged into the system. At the current time, the device ID
> > is already queried from the device and stored in the peak_usb_device
> > struct.
> >
> > This patch exports the device ID (called device_number in the struct)
> > as a sysfs attribute. The attribute name was chosen to be device_id
> > instead of device_number because the latter has been deprecated by Peak
> > in their API.
> >
> > Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
> > Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> > CC: Stephane Grosjean <s.grosjean@peak-system.com>
> > ---
> > V2: Update netdev_warn to output the mnemonic of the error value
> >
> > Resubmission of the patch. Also added Stéphane as maintainer in CC.
> >
> >  drivers/net/can/usb/peak_usb/pcan_usb_core.c | 18 ++++++++++++++++++
> >  1 file changed, 18 insertions(+)
> >
> > diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> > index 27b0a72fd885..7af3dd0a1b35 100644
> > --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> > +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> > @@ -15,6 +15,8 @@
> >  #include <linux/netdevice.h>
> >  #include <linux/usb.h>
> >  #include <linux/ethtool.h>
> > +#include <linux/device.h>
> > +#include <linux/sysfs.h>

Please sort the include files alphabetically.

> >  
> >  #include <linux/can.h>
> >  #include <linux/can/dev.h>
> > @@ -53,6 +55,15 @@ static const struct usb_device_id peak_usb_table[] = {
> >  
> >  MODULE_DEVICE_TABLE(usb, peak_usb_table);
> >  
> > +static ssize_t device_id_show(struct device *dev, struct device_attribute *attr, char *buf)
> > +{
> > +	struct net_device *netdev = to_net_dev(dev);
> > +	struct peak_usb_device *peak_dev = netdev_priv(netdev);
> > +
> > +	return sysfs_emit(buf, "%08X\n", peak_dev->device_number);
> > +}
> > +static DEVICE_ATTR_RO(device_id);
> > +
> >  /*
> >   * dump memory
> >   */
> > @@ -887,6 +898,11 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
> >  	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
> >  			peak_usb_adapter->name, ctrl_idx, dev->device_number);
> >  
> > +	err = device_create_file(&netdev->dev, &dev_attr_device_id);
> > +	/* Do not error out since device was configured successfully */
> > +	if (err)
> > +		netdev_warn(netdev, "unable to expose device_id via sysfs: %pe\n", ERR_PTR(err));
> > +

This is racy, please use a sysfs_groups instead, see
https://git.kernel.org/torvalds/c/3a5655a5b545e9647c3437473ee3d815fe1b9050

> >  	return 0;
> >  
> >  adap_dev_free:
> > @@ -923,6 +939,8 @@ static void peak_usb_disconnect(struct usb_interface *intf)
> >  		dev->state &= ~PCAN_USB_STATE_CONNECTED;
> >  		strlcpy(name, netdev->name, IFNAMSIZ);
> >  
> > +		device_remove_file(&netdev->dev, &dev_attr_device_id);
> > +
> >  		unregister_netdev(netdev);
> >  
> >  		kfree(dev->cmd_buf);
> 

regards,
Marc

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

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

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

* Re: [RESEND PATCH v2] can: peak_usb: export PCAN device ID as sysfs device attribute
  2022-09-30 12:06     ` Marc Kleine-Budde
@ 2022-09-30 14:20       ` Marc Kleine-Budde
  2022-10-22 21:57         ` Lukas Magel
  0 siblings, 1 reply; 48+ messages in thread
From: Marc Kleine-Budde @ 2022-09-30 14:20 UTC (permalink / raw)
  To: Lukas Magel; +Cc: Stephane Grosjean, linux-can

[-- Attachment #1: Type: text/plain, Size: 3996 bytes --]

On 30.09.2022 14:06:49, Marc Kleine-Budde wrote:
> On 28.09.2022 20:43:19, Lukas Magel wrote:
> > I was made aware by Stéphane that there has previously been discussion about
> > registering a sysfs file for reading and writing the device ID [1]. IMHO, I
> > believe the sysfs file approach would have one important advantage over using
> > ethtool: udev rule matching.
> > 
> > I often work with setups that feature several CAN interfaces. In such a setup, I
> > want to assign persistent interface names via udev in case device probing is not
> > deterministic or the devices are plugged in to different ports. At the moment,
> > the PEAK device driver and the underlying USB interface do not export any
> > practically usable identifier for discriminating between different interfaces of
> > the same type. The device ID solves this problem since it can be configured per
> > CAN interface to uniquely identify the interface. If the device ID is exported
> > as sysfs file, it is directly available for matching in udev rules via the
> > ATTR{...} key. This would solve the CAN interface identification problem and
> > allow easy read and write access to the device ID without Windows userspace tools.
> 
> I'm fine with a RO sysfs attribute. For writing the ethtool interface
> should be used instead.
> 
> Please document the sysfs entry in
> Documentation/ABI/testing/sysfs-class-net-FOO, with foo according to
> /sys/class/net/<iface>/FOO,

I mean with FOO the name of the driver, as in the target of the link
"/sys/class/net/<iface>/device/driver", which is peak_usb in this case.

> see "Documentation/ABI/testing/sysfs-class-net-grcan" as an example.

> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> index 27b0a72fd885..7af3dd0a1b35 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> @@ -15,6 +15,8 @@
>  #include <linux/netdevice.h>
>  #include <linux/usb.h>
>  #include <linux/ethtool.h>
> +#include <linux/device.h>
> +#include <linux/sysfs.h>
>  
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
> @@ -53,6 +55,15 @@ static const struct usb_device_id peak_usb_table[] = {
>  
>  MODULE_DEVICE_TABLE(usb, peak_usb_table);
>  
> +static ssize_t device_id_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +	struct net_device *netdev = to_net_dev(dev);
> +	struct peak_usb_device *peak_dev = netdev_priv(netdev);
> +
> +	return sysfs_emit(buf, "%08X\n", peak_dev->device_number);

I just noticed that the driver prints the device ID, but in decimal:

| ➜ (pts/0) frogger@riot:~ (master) journalctl -k|grep peak
| Sep 30 14:23:24 riot kernel: peak_usb 1-1.4:1.0: PEAK-System PCAN-USB FD v1 fw v3.2.0 (1 channels)
| Sep 30 14:23:24 riot kernel: peak_usb 1-1.4:1.0 can1: attached to PCAN-USB FD channel 0 (device 1144201745)
| Sep 30 14:23:24 riot kernel: usbcore: registered new interface driver peak_usb
| ➜ (pts/0) frogger@riot:~ (master) cat /sys/class/net/can1/device_id 
| 44332211

While the sysfs attribute is in hex. I have overwritten my original
device ID with 0x44332211 while testing Stéphane's patch. I'm wondering
if the serial number printed on the device's housing corresponds to the
default device ID. Is the printed device ID in hex or dec?

Mine is IPEH-004022-019814:
- it has leading zeros
- interpreted as hex, it doesn't fit into 32 bits
- interpreted as dec and converted into hex: 0xefbb26e6
  it would fit in 32 bits

If the default device ID corresponds to the printed-on number, do we
want to see/use this number in the sysfs, too?

regards,
Marc

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

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

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

* [PATCH 0/7] can: peak_usb: Introduce configurable user dev id
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
  2022-08-01 14:36 ` Vincent MAILHOL
  2022-09-15  9:54 ` [RESEND PATCH " Lukas Magel
@ 2022-10-22 21:35 ` Lukas Magel
  2022-10-22 21:35   ` [PATCH 1/7] can: peak_usb: rename device_id to a more explicit name Lukas Magel
                     ` (6 more replies)
  2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                   ` (10 subsequent siblings)
  13 siblings, 7 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-22 21:35 UTC (permalink / raw)
  To: linux-can

This series of patches introduces the user device id for the PEAK USB
CAN interfaces. The id can be read/written via ethtool and is exposed as
a read-only attribute via sysfs. This allows users to set the id via
ethtool and write udev rules to match against the sysfs attribute.

Most of the patches were originally introduced by Stéphane Grosjean and
have only been modified slightly. See the following threads for the
original patches:

* https://lore.kernel.org/linux-can/20220128150157.1222850-1-s.grosjean@peak-system.com/T/#mad8014c9f1c89a50d5944a50ae0a585edec79eab
* https://lore.kernel.org/linux-can/20211117150132.37056-1-s.grosjean@peak-system.com/T/#mbf1d7db8433734a1fe08868d79f9927a04fe7ffe

Stéphane Grosjean (5):
  can: peak_usb: rename device_id to a more explicit name
  can: peak_usb: add callback to read user value of CANFD
  can: peak_usb: allow flashing of the user device id
  can: peak_usb: replace unregister_netdev() with
  can: peak_usb: add ethtool interface to user defined

Lukas Magel (2):
  can: peak_usb: export PCAN user device ID as sysfs device
  can: peak_usb: align user device id format in log with

 .../ABI/testing/sysfs-class-net-peak_usb        |  15 +++
 drivers/net/can/usb/peak_usb/pcan_usb.c         |  43 ++++++-
 drivers/net/can/usb/peak_usb/pcan_usb_core.c    | 119 +++++++++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h    |  11 +-
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c      |  64 +++++++++-
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c     |  26 +++-
 drivers/net/can/usb/peak_usb/pcan_usb_pro.h     |   1 +
 7 files changed, 254 insertions(+), 25 deletions(-)



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

* [PATCH 1/7] can: peak_usb: rename device_id to a more explicit name
  2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
@ 2022-10-22 21:35   ` Lukas Magel
  2022-10-22 21:35   ` [PATCH 2/7] can: peak_usb: add callback to read user value of CANFD devices Lukas Magel
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-22 21:35 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

The so-called "device id" is in fact a value defined by the user.
Therefore, in order not to confuse it with the device id used by the USB,
the functions and variables for reading this user-defined value are
renamed.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      | 8 ++++----
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 6 +++---
 drivers/net/can/usb/peak_usb/pcan_usb_core.h | 4 ++--
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 2 +-
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  | 8 ++++----
 5 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 687dd542f7f6..11fd033b57f3 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -381,9 +381,9 @@ static int pcan_usb_get_serial(struct peak_usb_device *dev, u32 *serial_number)
 }
 
 /*
- * read device id from device
+ * read user device id from device
  */
-static int pcan_usb_get_device_id(struct peak_usb_device *dev, u32 *device_id)
+static int pcan_usb_get_user_devid(struct peak_usb_device *dev, u32 *user_devid)
 {
 	u8 args[PCAN_USB_CMD_ARGS_LEN];
 	int err;
@@ -393,7 +393,7 @@ static int pcan_usb_get_device_id(struct peak_usb_device *dev, u32 *device_id)
 		netdev_err(dev->netdev, "getting device id failure: %d\n", err);
 
 	else
-		*device_id = args[0];
+		*user_devid = args[0];
 
 	return err;
 }
@@ -1017,7 +1017,7 @@ const struct peak_usb_adapter pcan_usb = {
 	.dev_init = pcan_usb_init,
 	.dev_set_bus = pcan_usb_write_mode,
 	.dev_set_bittiming = pcan_usb_set_bittiming,
-	.dev_get_device_id = pcan_usb_get_device_id,
+	.dev_get_user_devid = pcan_usb_get_user_devid,
 	.dev_decode_buf = pcan_usb_decode_buf,
 	.dev_encode_msg = pcan_usb_encode_msg,
 	.dev_start = pcan_usb_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 225697d70a9a..8e1b3c19f92f 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -922,11 +922,11 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	}
 
 	/* get device number early */
-	if (dev->adapter->dev_get_device_id)
-		dev->adapter->dev_get_device_id(dev, &dev->device_number);
+	if (dev->adapter->dev_get_user_devid)
+		dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
 
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
-			peak_usb_adapter->name, ctrl_idx, dev->device_number);
+			peak_usb_adapter->name, ctrl_idx, dev->user_devid);
 
 	return 0;
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index f6bdd8b3f290..6ff32673a256 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -60,7 +60,7 @@ struct peak_usb_adapter {
 	int (*dev_set_data_bittiming)(struct peak_usb_device *dev,
 				      struct can_bittiming *bt);
 	int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff);
-	int (*dev_get_device_id)(struct peak_usb_device *dev, u32 *device_id);
+	int (*dev_get_user_devid)(struct peak_usb_device *dev, u32 *user_devid);
 	int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb);
 	int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb,
 					u8 *obuf, size_t *size);
@@ -122,7 +122,7 @@ struct peak_usb_device {
 	u8 *cmd_buf;
 	struct usb_anchor rx_submitted;
 
-	u32 device_number;
+	u32 user_devid;
 	u8 device_rev;
 
 	u8 ep_msg_in;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 2ea1500df393..b8053e697261 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -972,7 +972,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
 	}
 
 	pdev->usb_if->dev[dev->ctrl_idx] = dev;
-	dev->device_number =
+	dev->user_devid =
 		le32_to_cpu(pdev->usb_if->fw_info.dev_id[dev->ctrl_idx]);
 
 	/* if vendor rsp is of type 2, then it contains EP numbers to
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 5d8f6a40bb2c..15410d60cdf7 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -419,8 +419,8 @@ static int pcan_usb_pro_set_led(struct peak_usb_device *dev, u8 mode,
 	return pcan_usb_pro_send_cmd(dev, &um);
 }
 
-static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
-				      u32 *device_id)
+static int pcan_usb_pro_get_user_devid(struct peak_usb_device *dev,
+				       u32 *user_devid)
 {
 	struct pcan_usb_pro_devid *pdn;
 	struct pcan_usb_pro_msg um;
@@ -439,7 +439,7 @@ static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
 		return err;
 
 	pdn = (struct pcan_usb_pro_devid *)pc;
-	*device_id = le32_to_cpu(pdn->dev_num);
+	*user_devid = le32_to_cpu(pdn->dev_num);
 
 	return err;
 }
@@ -1076,7 +1076,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	.dev_free = pcan_usb_pro_free,
 	.dev_set_bus = pcan_usb_pro_set_bus,
 	.dev_set_bittiming = pcan_usb_pro_set_bittiming,
-	.dev_get_device_id = pcan_usb_pro_get_device_id,
+	.dev_get_user_devid = pcan_usb_pro_get_user_devid,
 	.dev_decode_buf = pcan_usb_pro_decode_buf,
 	.dev_encode_msg = pcan_usb_pro_encode_msg,
 	.dev_start = pcan_usb_pro_start,
-- 
2.37.2


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

* [PATCH 2/7] can: peak_usb: add callback to read user value of CANFD devices
  2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
  2022-10-22 21:35   ` [PATCH 1/7] can: peak_usb: rename device_id to a more explicit name Lukas Magel
@ 2022-10-22 21:35   ` Lukas Magel
  2022-10-22 21:35   ` [PATCH 3/7] can: peak_usb: allow flashing of the user device id Lukas Magel
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-22 21:35 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch adds the specific function that allows to read a user defined
value from the non volatile memory of the USB CANFD interfaces of
PEAK-System.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c |  3 +-
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 33 +++++++++++++++++---
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 8e1b3c19f92f..ca282b0aa9a5 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -922,8 +922,7 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	}
 
 	/* get device number early */
-	if (dev->adapter->dev_get_user_devid)
-		dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
+	dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
 
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
 			peak_usb_adapter->name, ctrl_idx, dev->user_devid);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index b8053e697261..2db358d0295e 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -234,6 +234,15 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
 	return err;
 }
 
+static int pcan_usb_fd_read_fwinfo(struct peak_usb_device *dev,
+				   struct pcan_ufd_fw_info *fw_info)
+{
+	return pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
+				     PCAN_USBPRO_INFO_FW,
+				     fw_info,
+				     sizeof(*fw_info));
+}
+
 /* build the commands list in the given buffer, to enter operational mode */
 static int pcan_usb_fd_build_restart_cmd(struct peak_usb_device *dev, u8 *buf)
 {
@@ -434,6 +443,21 @@ static int pcan_usb_fd_set_bittiming_fast(struct peak_usb_device *dev,
 	return pcan_usb_fd_send_cmd(dev, ++cmd);
 }
 
+/* read user device id from device */
+static int pcan_usb_fd_get_user_devid(struct peak_usb_device *dev,
+				      u32 *user_devid)
+{
+	int err;
+	struct pcan_usb_fd_if *usb_if = pcan_usb_fd_dev_if(dev);
+
+	err = pcan_usb_fd_read_fwinfo(dev, &usb_if->fw_info);
+	if (err)
+		return err;
+
+	*user_devid = le32_to_cpu(usb_if->fw_info.dev_id[dev->ctrl_idx]);
+	return err;
+}
+
 /* handle restart but in asynchronously way
  * (uses PCAN-USB Pro code to complete asynchronous request)
  */
@@ -907,10 +931,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
 
 		fw_info = &pdev->usb_if->fw_info;
 
-		err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
-					    PCAN_USBPRO_INFO_FW,
-					    fw_info,
-					    sizeof(*fw_info));
+		err = pcan_usb_fd_read_fwinfo(dev, fw_info);
 		if (err) {
 			dev_err(dev->netdev->dev.parent,
 				"unable to read %s firmware info (err %d)\n",
@@ -1148,6 +1169,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1222,6 +1244,7 @@ const struct peak_usb_adapter pcan_usb_chip = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1296,6 +1319,7 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1370,6 +1394,7 @@ const struct peak_usb_adapter pcan_usb_x6 = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
-- 
2.37.2


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

* [PATCH 3/7] can: peak_usb: allow flashing of the user device id
  2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
  2022-10-22 21:35   ` [PATCH 1/7] can: peak_usb: rename device_id to a more explicit name Lukas Magel
  2022-10-22 21:35   ` [PATCH 2/7] can: peak_usb: add callback to read user value of CANFD devices Lukas Magel
@ 2022-10-22 21:35   ` Lukas Magel
  2022-10-22 21:35   ` [PATCH 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-22 21:35 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This series of patches adds a callback that allows the user to flash a
self-defined device id to all USB - CAN/CANFD interfaces of PEAK-System
managed by this driver, namely:
- PCAN-USB
- PCAN-USB FD
- PCAN-USB Pro FD
- PCAN-USB X6
- PCAN-Chip USB
- PCAN-USB Pro

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      | 26 ++++++++++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 26 ++++++++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  | 15 +++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.h  |  1 +
 5 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 11fd033b57f3..6c01b2c6212b 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -9,10 +9,12 @@
  * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
  */
 #include <asm/unaligned.h>
+
+#include <linux/ethtool.h>
+#include <linux/limits.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -398,6 +400,25 @@ static int pcan_usb_get_user_devid(struct peak_usb_device *dev, u32 *user_devid)
 	return err;
 }
 
+/* set a new user device id in the flash memory of the device */
+static int pcan_usb_set_user_devid(struct peak_usb_device *dev, u32 user_devid)
+{
+	u8 args[PCAN_USB_CMD_ARGS_LEN];
+
+	/* this kind of device supports 8-bit values only */
+	if (user_devid > U8_MAX)
+		return -EINVAL;
+
+	/* during the flash process the device disconnects during ~1.25 s.:
+	 * prohibit access when interface is UP
+	 */
+	if (dev->netdev->flags & IFF_UP)
+		return -EBUSY;
+
+	args[0] = user_devid;
+	return pcan_usb_send_cmd(dev, PCAN_USB_CMD_DEVID, PCAN_USB_SET, args);
+}
+
 /*
  * update current time ref with received timestamp
  */
@@ -1018,6 +1039,7 @@ const struct peak_usb_adapter pcan_usb = {
 	.dev_set_bus = pcan_usb_write_mode,
 	.dev_set_bittiming = pcan_usb_set_bittiming,
 	.dev_get_user_devid = pcan_usb_get_user_devid,
+	.dev_set_user_devid = pcan_usb_set_user_devid,
 	.dev_decode_buf = pcan_usb_decode_buf,
 	.dev_encode_msg = pcan_usb_encode_msg,
 	.dev_start = pcan_usb_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 6ff32673a256..d9c9e333c47a 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -61,6 +61,7 @@ struct peak_usb_adapter {
 				      struct can_bittiming *bt);
 	int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff);
 	int (*dev_get_user_devid)(struct peak_usb_device *dev, u32 *user_devid);
+	int (*dev_set_user_devid)(struct peak_usb_device *dev, u32 user_devid);
 	int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb);
 	int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb,
 					u8 *obuf, size_t *size);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 2db358d0295e..1f5ad0dc2b1c 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -147,6 +147,15 @@ struct __packed pcan_ufd_ovr_msg {
 	u8	unused[3];
 };
 
+#define PCAN_UFD_CMD_DEVID_SET		0x81
+
+struct __packed pcan_ufd_device_id {
+	__le16	opcode_channel;
+
+	u16	unused;
+	__le32	device_id;
+};
+
 static inline int pufd_omsg_get_channel(struct pcan_ufd_ovr_msg *om)
 {
 	return om->channel & 0xf;
@@ -458,6 +467,19 @@ static int pcan_usb_fd_get_user_devid(struct peak_usb_device *dev,
 	return err;
 }
 
+/* set a new user device id in the flash memory of the device */
+static int pcan_usb_fd_set_user_devid(struct peak_usb_device *dev, u32 devid)
+{
+	struct pcan_ufd_device_id *cmd = pcan_usb_fd_cmd_buffer(dev);
+
+	cmd->opcode_channel = pucan_cmd_opcode_channel(dev->ctrl_idx,
+						       PCAN_UFD_CMD_DEVID_SET);
+	cmd->device_id = cpu_to_le32(devid);
+
+	/* send the command */
+	return pcan_usb_fd_send_cmd(dev, ++cmd);
+}
+
 /* handle restart but in asynchronously way
  * (uses PCAN-USB Pro code to complete asynchronous request)
  */
@@ -1170,6 +1192,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
+	.dev_set_user_devid = pcan_usb_fd_set_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1245,6 +1268,7 @@ const struct peak_usb_adapter pcan_usb_chip = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
+	.dev_set_user_devid = pcan_usb_fd_set_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1320,6 +1344,7 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
+	.dev_set_user_devid = pcan_usb_fd_set_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1395,6 +1420,7 @@ const struct peak_usb_adapter pcan_usb_x6 = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
+	.dev_set_user_devid = pcan_usb_fd_set_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 15410d60cdf7..d3731c5aa4ed 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -76,6 +76,7 @@ static u16 pcan_usb_pro_sizeof_rec[256] = {
 	[PCAN_USBPRO_SETFILTR] = sizeof(struct pcan_usb_pro_filter),
 	[PCAN_USBPRO_SETTS] = sizeof(struct pcan_usb_pro_setts),
 	[PCAN_USBPRO_GETDEVID] = sizeof(struct pcan_usb_pro_devid),
+	[PCAN_USBPRO_SETDEVID] = sizeof(struct pcan_usb_pro_devid),
 	[PCAN_USBPRO_SETLED] = sizeof(struct pcan_usb_pro_setled),
 	[PCAN_USBPRO_RXMSG8] = sizeof(struct pcan_usb_pro_rxmsg),
 	[PCAN_USBPRO_RXMSG4] = sizeof(struct pcan_usb_pro_rxmsg) - 4,
@@ -149,6 +150,7 @@ static int pcan_msg_add_rec(struct pcan_usb_pro_msg *pm, int id, ...)
 
 	case PCAN_USBPRO_SETBTR:
 	case PCAN_USBPRO_GETDEVID:
+	case PCAN_USBPRO_SETDEVID:
 		*pc++ = va_arg(ap, int);
 		pc += 2;
 		*(__le32 *)pc = cpu_to_le32(va_arg(ap, u32));
@@ -444,6 +446,18 @@ static int pcan_usb_pro_get_user_devid(struct peak_usb_device *dev,
 	return err;
 }
 
+static int pcan_usb_pro_set_user_devid(struct peak_usb_device *dev,
+				       u32 user_devid)
+{
+	struct pcan_usb_pro_msg um;
+
+	pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+	pcan_msg_add_rec(&um, PCAN_USBPRO_SETDEVID, dev->ctrl_idx,
+			 user_devid);
+
+	return pcan_usb_pro_send_cmd(dev, &um);
+}
+
 static int pcan_usb_pro_set_bittiming(struct peak_usb_device *dev,
 				      struct can_bittiming *bt)
 {
@@ -1077,6 +1091,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	.dev_set_bus = pcan_usb_pro_set_bus,
 	.dev_set_bittiming = pcan_usb_pro_set_bittiming,
 	.dev_get_user_devid = pcan_usb_pro_get_user_devid,
+	.dev_set_user_devid = pcan_usb_pro_set_user_devid,
 	.dev_decode_buf = pcan_usb_pro_decode_buf,
 	.dev_encode_msg = pcan_usb_pro_encode_msg,
 	.dev_start = pcan_usb_pro_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
index a34e0fc021c9..28e740af905d 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
@@ -62,6 +62,7 @@ struct __packed pcan_usb_pro_fwinfo {
 #define PCAN_USBPRO_SETBTR	0x02
 #define PCAN_USBPRO_SETBUSACT	0x04
 #define PCAN_USBPRO_SETSILENT	0x05
+#define PCAN_USBPRO_SETDEVID	0x06
 #define PCAN_USBPRO_SETFILTR	0x0a
 #define PCAN_USBPRO_SETTS	0x10
 #define PCAN_USBPRO_GETDEVID	0x12
-- 
2.37.2


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

* [PATCH 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev()
  2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                     ` (2 preceding siblings ...)
  2022-10-22 21:35   ` [PATCH 3/7] can: peak_usb: allow flashing of the user device id Lukas Magel
@ 2022-10-22 21:35   ` Lukas Magel
  2022-10-25 13:30     ` Marc Kleine-Budde
  2022-10-22 21:35   ` [PATCH 5/7] can: peak_usb: add ethtool interface to user defined flashed device number Lukas Magel
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 48+ messages in thread
From: Lukas Magel @ 2022-10-22 21:35 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch changes call to unregister_netdev() with unregister_candev().

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index ca282b0aa9a5..b010b546f6d1 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -963,7 +963,7 @@ static void peak_usb_disconnect(struct usb_interface *intf)
 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
 		strscpy(name, netdev->name, IFNAMSIZ);
 
-		unregister_netdev(netdev);
+		unregister_candev(netdev);
 
 		kfree(dev->cmd_buf);
 		dev->next_siblings = NULL;
-- 
2.37.2


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

* [PATCH 5/7] can: peak_usb: add ethtool interface to user defined flashed device number
  2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                     ` (3 preceding siblings ...)
  2022-10-22 21:35   ` [PATCH 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
@ 2022-10-22 21:35   ` Lukas Magel
  2022-10-25 14:54     ` Marc Kleine-Budde
  2022-10-22 21:35   ` [PATCH 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute Lukas Magel
  2022-10-22 21:35   ` [PATCH 7/7] can: peak_usb: align user device id format in log with sysfs attribute Lukas Magel
  6 siblings, 1 reply; 48+ messages in thread
From: Lukas Magel @ 2022-10-22 21:35 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch introduces 3 new functions implementing support for eeprom
access of USB - CAN network interfaces managed by the driver, through the
ethtool interface. All of them (except the PCAN-USB interface) interpret
the 4 data bytes as a 32-bit value to be read/write in the non-volatile
memory of the device. The PCAN-USB only manages a single byte value.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      |  9 +++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 80 ++++++++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  6 ++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  3 +
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  3 +
 5 files changed, 101 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 6c01b2c6212b..d205da827016 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -984,9 +984,18 @@ static int pcan_usb_set_phys_id(struct net_device *netdev,
 	return err;
 }
 
+/* This device only handles 8-bit user device id. */
+static int pcan_usb_get_eeprom_len(struct net_device *netdev)
+{
+	return sizeof(u8);
+}
+
 static const struct ethtool_ops pcan_usb_ethtool_ops = {
 	.set_phys_id = pcan_usb_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= pcan_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /*
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index b010b546f6d1..438788732c2c 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -808,6 +808,86 @@ static const struct net_device_ops peak_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+/* CAN-USB devices generally handle 32-bit user device id.
+ * In case one doesn't, then it have to overload this function.
+ */
+int peak_usb_get_eeprom_len(struct net_device *netdev)
+{
+	return sizeof(u32);
+}
+
+/* Every CAN-USB device exports the dev_get_user_devid() operation. It is used
+ * here to fill the data buffer with the user defined device number.
+ */
+int peak_usb_get_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct peak_usb_device *dev = netdev_priv(netdev);
+	u32 devid;
+	u32 devid_le;
+	int err;
+
+	err = dev->adapter->dev_get_user_devid(dev, &devid);
+	if (err)
+		return err;
+
+	/* ethtool operates on individual bytes. The byte order of the user
+	 * device id in memory depends on the kernel architecture. We
+	 * convert the user device id back to the native byte order of the PEAK
+	 * device itself to ensure that the order is consistent for all
+	 * host architectures.
+	 */
+	devid_le = cpu_to_le32(devid);
+	memcpy(data, (u8 *)&devid_le + eeprom->offset, eeprom->len);
+
+	/* update cached value */
+	dev->user_devid = devid;
+	return err;
+}
+
+/* Every CAN-USB device exports the dev_get_user_devid()/dev_set_user_devid()
+ * operations. They are used here to set the new user defined device number.
+ */
+int peak_usb_set_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct peak_usb_device *dev = netdev_priv(netdev);
+	u32 devid;
+	u32 devid_le;
+	int err;
+
+	/* first, read the current user defined device value number */
+	err = dev->adapter->dev_get_user_devid(dev, &devid);
+	if (err) {
+		netdev_err(netdev, "Failed to init device id (err %d)\n", err);
+		return err;
+	}
+
+	/* do update the value with user given bytes.
+	 * ethtool operates on individual bytes. The byte order of the user
+	 * device id in memory depends on the kernel architecture. We
+	 * convert the user device id back to the native byte order of the PEAK
+	 * device itself to ensure that the order is consistent for all
+	 * host architectures.
+	 */
+	devid_le = cpu_to_le32(devid);
+	memcpy((u8 *)&devid_le + eeprom->offset, data, eeprom->len);
+	devid = le32_to_cpu(devid_le);
+
+	/* flash the new value now */
+	err = dev->adapter->dev_set_user_devid(dev, devid);
+	if (err) {
+		netdev_err(netdev, "Failed to write new device id (err %d)\n",
+			   err);
+		return err;
+	}
+
+	/* update cached value with the new one */
+	dev->user_devid = devid;
+
+	return 0;
+}
+
 int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
 {
 	info->so_timestamping =
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index d9c9e333c47a..a4a43edc0456 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -148,4 +148,10 @@ void peak_usb_async_complete(struct urb *urb);
 void peak_usb_restart_complete(struct peak_usb_device *dev);
 int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
 
+/* common 32-bit devid ethtool management */
+int peak_usb_get_eeprom_len(struct net_device *netdev);
+int peak_usb_get_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data);
+int peak_usb_set_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data);
 #endif
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 1f5ad0dc2b1c..5188915c4299 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1124,6 +1124,9 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
 	.set_phys_id = pcan_usb_fd_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= peak_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /* describes the PCAN-USB FD adapter */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index d3731c5aa4ed..d45e6562a4bb 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -1037,6 +1037,9 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
 	.set_phys_id = pcan_usb_pro_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= peak_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /*
-- 
2.37.2


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

* [PATCH 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute
  2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                     ` (4 preceding siblings ...)
  2022-10-22 21:35   ` [PATCH 5/7] can: peak_usb: add ethtool interface to user defined flashed device number Lukas Magel
@ 2022-10-22 21:35   ` Lukas Magel
  2022-10-25 13:30     ` Marc Kleine-Budde
  2022-10-22 21:35   ` [PATCH 7/7] can: peak_usb: align user device id format in log with sysfs attribute Lukas Magel
  6 siblings, 1 reply; 48+ messages in thread
From: Lukas Magel @ 2022-10-22 21:35 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel, Stephane Grosjean

This patch exports the user device ID as a sysfs attribute. This allows
users to easily read the ID and to write udev rules that can match against
the ID.

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
---
 .../ABI/testing/sysfs-class-net-peak_usb      | 15 ++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c  | 30 +++++++++++++++++--
 2 files changed, 42 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-peak_usb

diff --git a/Documentation/ABI/testing/sysfs-class-net-peak_usb b/Documentation/ABI/testing/sysfs-class-net-peak_usb
new file mode 100644
index 000000000000..f7f23f9bdfde
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-peak_usb
@@ -0,0 +1,15 @@
+
+What:		/sys/class/net/<iface>/peak_usb/user_devid
+Date:		October 2022
+KernelVersion:	6.1
+Contact:	Stephane Grosjean <s.grosjean@peak-system.com>
+Description:
+		PEAK PCAN-USB devices support a user-configurable device
+		identifier. This attribute provides read-only access to the
+		currently configured value of the device identifier. Depending
+		on the device type, the identifier has a length of 8 or 32 bit.
+		The value read from this attribute is always an 8 digit 32 bit
+		hexadecimal value in big endian format. If the device only
+		supports an 8 bit identifier, the upper 24 bit of the value are
+		set to zero.
+
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 438788732c2c..fbefd4f05e08 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -8,13 +8,15 @@
  *
  * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
  */
+#include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/init.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
 #include <linux/usb.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -53,6 +55,25 @@ static const struct usb_device_id peak_usb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, peak_usb_table);
 
+static ssize_t user_devid_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct net_device *netdev = to_net_dev(dev);
+	struct peak_usb_device *peak_dev = netdev_priv(netdev);
+
+	return sysfs_emit(buf, "%08X\n", peak_dev->user_devid);
+}
+static DEVICE_ATTR_RO(user_devid);
+
+static const struct attribute *peak_usb_sysfs_attrs[] = {
+	&dev_attr_user_devid.attr,
+	NULL,
+};
+
+static const struct attribute_group peak_usb_sysfs_group = {
+	.name	= "peak_usb",
+	.attrs	= (struct attribute **)peak_usb_sysfs_attrs,
+};
+
 /*
  * dump memory
  */
@@ -961,6 +982,9 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	/* add ethtool support */
 	netdev->ethtool_ops = peak_usb_adapter->ethtool_ops;
 
+	/* register peak_usb sysfs files */
+	netdev->sysfs_groups[0] = &peak_usb_sysfs_group;
+
 	init_usb_anchor(&dev->rx_submitted);
 
 	init_usb_anchor(&dev->tx_submitted);
-- 
2.37.2


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

* [PATCH 7/7] can: peak_usb: align user device id format in log with sysfs attribute
  2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                     ` (5 preceding siblings ...)
  2022-10-22 21:35   ` [PATCH 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute Lukas Magel
@ 2022-10-22 21:35   ` Lukas Magel
  2022-10-25 11:28     ` Marc Kleine-Budde
  6 siblings, 1 reply; 48+ messages in thread
From: Lukas Magel @ 2022-10-22 21:35 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel

Previously, the user device id was printed to the kernel log in decimal
upon connecting a new PEAK device. This behavior is inconsistent with
the hexadecimal format of the user device id sysfs attribute. This patch
updates the log message to output the id in hexadecimal.

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index fbefd4f05e08..8bb9a3fa686c 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -1028,8 +1028,8 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	/* get device number early */
 	dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
 
-	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
-			peak_usb_adapter->name, ctrl_idx, dev->user_devid);
+	netdev_info(netdev, "attached to %s channel %u (device %08Xh)\n",
+		    peak_usb_adapter->name, ctrl_idx, dev->user_devid);
 
 	return 0;
 
-- 
2.37.2


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

* Re: [RESEND PATCH v2] can: peak_usb: export PCAN device ID as sysfs device attribute
  2022-09-30 14:20       ` Marc Kleine-Budde
@ 2022-10-22 21:57         ` Lukas Magel
  0 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-22 21:57 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: Stephane Grosjean, linux-can

On 30.09.22 16:20, Marc Kleine-Budde wrote:
> On 30.09.2022 14:06:49, Marc Kleine-Budde wrote:
>> On 28.09.2022 20:43:19, Lukas Magel wrote:
>>> I was made aware by Stéphane that there has previously been discussion about
>>> registering a sysfs file for reading and writing the device ID [1]. IMHO, I
>>> believe the sysfs file approach would have one important advantage over using
>>> ethtool: udev rule matching.
>>>
>>> I often work with setups that feature several CAN interfaces. In such a setup, I
>>> want to assign persistent interface names via udev in case device probing is not
>>> deterministic or the devices are plugged in to different ports. At the moment,
>>> the PEAK device driver and the underlying USB interface do not export any
>>> practically usable identifier for discriminating between different interfaces of
>>> the same type. The device ID solves this problem since it can be configured per
>>> CAN interface to uniquely identify the interface. If the device ID is exported
>>> as sysfs file, it is directly available for matching in udev rules via the
>>> ATTR{...} key. This would solve the CAN interface identification problem and
>>> allow easy read and write access to the device ID without Windows userspace tools.
>> I'm fine with a RO sysfs attribute. For writing the ethtool interface
>> should be used instead.
I submitted a series of patches to the thread that merge the previous patches
by Stéphane to introduce RW ethtool access and RO access via the sysfs
attribute.
>>
>> Please document the sysfs entry in
>> Documentation/ABI/testing/sysfs-class-net-FOO, with foo according to
>> /sys/class/net/<iface>/FOO,
> I mean with FOO the name of the driver, as in the target of the link
> "/sys/class/net/<iface>/device/driver", which is peak_usb in this case.
>
>> see "Documentation/ABI/testing/sysfs-class-net-grcan" as an example.
>> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
>> index 27b0a72fd885..7af3dd0a1b35 100644
>> --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
>> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
>> @@ -15,6 +15,8 @@
>>  #include <linux/netdevice.h>
>>  #include <linux/usb.h>
>>  #include <linux/ethtool.h>
>> +#include <linux/device.h>
>> +#include <linux/sysfs.h>
>>  
>>  #include <linux/can.h>
>>  #include <linux/can/dev.h>
>> @@ -53,6 +55,15 @@ static const struct usb_device_id peak_usb_table[] = {
>>  
>>  MODULE_DEVICE_TABLE(usb, peak_usb_table);
>>  
>> +static ssize_t device_id_show(struct device *dev, struct device_attribute *attr, char *buf)
>> +{
>> +	struct net_device *netdev = to_net_dev(dev);
>> +	struct peak_usb_device *peak_dev = netdev_priv(netdev);
>> +
>> +	return sysfs_emit(buf, "%08X\n", peak_dev->device_number);
> I just noticed that the driver prints the device ID, but in decimal:
>
> | ➜ (pts/0) frogger@riot:~ (master) journalctl -k|grep peak
> | Sep 30 14:23:24 riot kernel: peak_usb 1-1.4:1.0: PEAK-System PCAN-USB FD v1 fw v3.2.0 (1 channels)
> | Sep 30 14:23:24 riot kernel: peak_usb 1-1.4:1.0 can1: attached to PCAN-USB FD channel 0 (device 1144201745)
> | Sep 30 14:23:24 riot kernel: usbcore: registered new interface driver peak_usb
> | ➜ (pts/0) frogger@riot:~ (master) cat /sys/class/net/can1/device_id 
> | 44332211
>
> While the sysfs attribute is in hex. I have overwritten my original
> device ID with 0x44332211 while testing Stéphane's patch. I'm wondering
> if the serial number printed on the device's housing corresponds to the
> default device ID. Is the printed device ID in hex or dec?
>
> Mine is IPEH-004022-019814:
> - it has leading zeros
> - interpreted as hex, it doesn't fit into 32 bits
> - interpreted as dec and converted into hex: 0xefbb26e6
>   it would fit in 32 bits
>
> If the default device ID corresponds to the printed-on number, do we
> want to see/use this number in the sysfs, too?

I did some checking for the PCAN USB FD device, but I couldn't find a trace
of this serial number. The ser_no attribute in the fw_info struct is zero for
my device. Maybe Stéphane can shed some more light on this number?

>
> regards,
> Marc
>

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

* Re: [PATCH 7/7] can: peak_usb: align user device id format in log with sysfs attribute
  2022-10-22 21:35   ` [PATCH 7/7] can: peak_usb: align user device id format in log with sysfs attribute Lukas Magel
@ 2022-10-25 11:28     ` Marc Kleine-Budde
  2022-10-25 11:44       ` Marc Kleine-Budde
  0 siblings, 1 reply; 48+ messages in thread
From: Marc Kleine-Budde @ 2022-10-25 11:28 UTC (permalink / raw)
  To: Lukas Magel; +Cc: linux-can

[-- Attachment #1: Type: text/plain, Size: 1704 bytes --]

On 22.10.2022 21:35:35, Lukas Magel wrote:
> Previously, the user device id was printed to the kernel log in decimal
> upon connecting a new PEAK device. This behavior is inconsistent with
> the hexadecimal format of the user device id sysfs attribute. This patch
> updates the log message to output the id in hexadecimal.
> 
> Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
> ---
>  drivers/net/can/usb/peak_usb/pcan_usb_core.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> index fbefd4f05e08..8bb9a3fa686c 100644
> --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> @@ -1028,8 +1028,8 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
>  	/* get device number early */
>  	dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
>  
> -	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
> -			peak_usb_adapter->name, ctrl_idx, dev->user_devid);
> +	netdev_info(netdev, "attached to %s channel %u (device %08Xh)\n",
                                                                  ^^
Why is the a trailing 'h'? To denote that it's a hexadecimal value?

> +		    peak_usb_adapter->name, ctrl_idx, dev->user_devid);
>  
>  	return 0;
>  
> -- 
> 2.37.2
> 
> 

Marc

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

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

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

* Re: [PATCH 7/7] can: peak_usb: align user device id format in log with sysfs attribute
  2022-10-25 11:28     ` Marc Kleine-Budde
@ 2022-10-25 11:44       ` Marc Kleine-Budde
  0 siblings, 0 replies; 48+ messages in thread
From: Marc Kleine-Budde @ 2022-10-25 11:44 UTC (permalink / raw)
  To: Lukas Magel; +Cc: linux-can

[-- Attachment #1: Type: text/plain, Size: 1838 bytes --]

On 25.10.2022 13:28:37, Marc Kleine-Budde wrote:
> On 22.10.2022 21:35:35, Lukas Magel wrote:
> > Previously, the user device id was printed to the kernel log in decimal
> > upon connecting a new PEAK device. This behavior is inconsistent with
> > the hexadecimal format of the user device id sysfs attribute. This patch
> > updates the log message to output the id in hexadecimal.
> > 
> > Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
> > ---
> >  drivers/net/can/usb/peak_usb/pcan_usb_core.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> > index fbefd4f05e08..8bb9a3fa686c 100644
> > --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> > +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
> > @@ -1028,8 +1028,8 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
> >  	/* get device number early */
> >  	dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
> >  
> > -	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
> > -			peak_usb_adapter->name, ctrl_idx, dev->user_devid);
> > +	netdev_info(netdev, "attached to %s channel %u (device %08Xh)\n",
>                                                                   ^^
> Why is the a trailing 'h'? To denote that it's a hexadecimal value?

Probably because it says so in Windows, as shown on page 18 in:

| https://www.peak-system.com/produktcd/Pdf/English/PCAN-USB-FD_UserMan_eng.pdf

Marc

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

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

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

* Re: [PATCH 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev()
  2022-10-22 21:35   ` [PATCH 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
@ 2022-10-25 13:30     ` Marc Kleine-Budde
  0 siblings, 0 replies; 48+ messages in thread
From: Marc Kleine-Budde @ 2022-10-25 13:30 UTC (permalink / raw)
  To: Lukas Magel; +Cc: linux-can, Stephane Grosjean

[-- Attachment #1: Type: text/plain, Size: 554 bytes --]

On 22.10.2022 21:35:32, Lukas Magel wrote:
> From: Stephane Grosjean <s.grosjean@peak-system.com>
> 
> This patch changes call to unregister_netdev() with unregister_candev().
> 
> Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>

Your S-o-b is missing.

Marc

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

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

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

* Re: [PATCH 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute
  2022-10-22 21:35   ` [PATCH 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute Lukas Magel
@ 2022-10-25 13:30     ` Marc Kleine-Budde
  0 siblings, 0 replies; 48+ messages in thread
From: Marc Kleine-Budde @ 2022-10-25 13:30 UTC (permalink / raw)
  To: Lukas Magel; +Cc: linux-can, Stephane Grosjean

[-- Attachment #1: Type: text/plain, Size: 658 bytes --]

On 22.10.2022 21:35:34, Lukas Magel wrote:
> This patch exports the user device ID as a sysfs attribute. This allows
> users to easily read the ID and to write udev rules that can match against
> the ID.
> 
> Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
> Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>

Nitpick: your S-o-b should be the last one.

Marc

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

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

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

* Re: [PATCH 5/7] can: peak_usb: add ethtool interface to user defined flashed device number
  2022-10-22 21:35   ` [PATCH 5/7] can: peak_usb: add ethtool interface to user defined flashed device number Lukas Magel
@ 2022-10-25 14:54     ` Marc Kleine-Budde
  0 siblings, 0 replies; 48+ messages in thread
From: Marc Kleine-Budde @ 2022-10-25 14:54 UTC (permalink / raw)
  To: Lukas Magel; +Cc: linux-can, Stephane Grosjean

[-- Attachment #1: Type: text/plain, Size: 1656 bytes --]

On 22.10.2022 21:35:33, Lukas Magel wrote:
> From: Stephane Grosjean <s.grosjean@peak-system.com>
> 
> This patch introduces 3 new functions implementing support for eeprom
> access of USB - CAN network interfaces managed by the driver, through the
> ethtool interface. All of them (except the PCAN-USB interface) interpret
> the 4 data bytes as a 32-bit value to be read/write in the non-volatile
> memory of the device. The PCAN-USB only manages a single byte value.
> 
> Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
> Signed-off-by: Lukas Magel <lukas.magel@posteo.net>

If you compile with "C=1" sparse complains about:

| drivers/net/can/usb/peak_usb/pcan_usb_core.c:861:18: warning: incorrect type in assignment (different base types)
| drivers/net/can/usb/peak_usb/pcan_usb_core.c:861:18:    expected unsigned int [usertype] devid_le
| drivers/net/can/usb/peak_usb/pcan_usb_core.c:861:18:    got restricted __le32 [usertype]
| drivers/net/can/usb/peak_usb/pcan_usb_core.c:894:18: warning: incorrect type in assignment (different base types)
| drivers/net/can/usb/peak_usb/pcan_usb_core.c:894:18:    expected unsigned int [usertype] devid_le
| drivers/net/can/usb/peak_usb/pcan_usb_core.c:894:18:    got restricted __le32 [usertype]
| drivers/net/can/usb/peak_usb/pcan_usb_core.c:896:17: warning: cast to restricted __le32

regards,
Marc

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

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

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

* [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (2 preceding siblings ...)
  2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
@ 2022-10-30 10:59 ` Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 1/7] can: peak_usb: rename device_id to a more explicit name Lukas Magel
                     ` (6 more replies)
  2022-12-13  8:03 ` [PATCH v3 0/7] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
                   ` (9 subsequent siblings)
  13 siblings, 7 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-30 10:59 UTC (permalink / raw)
  To: linux-can

This series of patches introduces the user device id for the PEAK USB
CAN interfaces. The id can be read/written via ethtool and is exposed as
a read-only attribute via sysfs. This allows users to set the id via
ethtool and write udev rules to match against the sysfs attribute.

Most of the patches were originally introduced by Stéphane Grosjean and
have only been modified slightly. See the following threads for the
original patches:

* https://lore.kernel.org/linux-can/20220128150157.1222850-1-s.grosjean@peak-system.com/T/#mad8014c9f1c89a50d5944a50ae0a585edec79eab
* https://lore.kernel.org/linux-can/20211117150132.37056-1-s.grosjean@peak-system.com/T/#mbf1d7db8433734a1fe08868d79f9927a04fe7ffe

v2:
* Fix type of devid_le in ethtool peak_usb_(get|set)_eeprom
* Fix signed-off tags

Stéphane Grosjean (5):
  can: peak_usb: rename device_id to a more explicit name
  can: peak_usb: add callback to read user value of CANFD
  can: peak_usb: allow flashing of the user device id
  can: peak_usb: replace unregister_netdev() with
  can: peak_usb: add ethtool interface to user defined

Lukas Magel (2):
  can: peak_usb: export PCAN user device ID as sysfs device
  can: peak_usb: align user device id format in log with

.../ABI/testing/sysfs-class-net-peak_usb        |  15 +++
drivers/net/can/usb/peak_usb/pcan_usb.c         |  43 ++++++-
drivers/net/can/usb/peak_usb/pcan_usb_core.c    | 119 +++++++++++++++++--
drivers/net/can/usb/peak_usb/pcan_usb_core.h    |  11 +-
drivers/net/can/usb/peak_usb/pcan_usb_fd.c      |  64 +++++++++-
drivers/net/can/usb/peak_usb/pcan_usb_pro.c     |  26 +++-
drivers/net/can/usb/peak_usb/pcan_usb_pro.h     |   1 +
7 files changed, 254 insertions(+), 25 deletions(-)

---
@Marc: Thanks for the feedback. I naively left out my tag because I
hadn't modified patch 5. I should have reread the kernel doc on the tags
first.


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

* [PATCH v2 1/7] can: peak_usb: rename device_id to a more explicit name
  2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
@ 2022-10-30 10:59   ` Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 2/7] can: peak_usb: add callback to read user value of CANFD devices Lukas Magel
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-30 10:59 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

The so-called "device id" is in fact a value defined by the user.
Therefore, in order not to confuse it with the device id used by the USB,
the functions and variables for reading this user-defined value are
renamed.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      | 8 ++++----
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 6 +++---
 drivers/net/can/usb/peak_usb/pcan_usb_core.h | 4 ++--
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 2 +-
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  | 8 ++++----
 5 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 687dd542f7f6..11fd033b57f3 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -381,9 +381,9 @@ static int pcan_usb_get_serial(struct peak_usb_device *dev, u32 *serial_number)
 }
 
 /*
- * read device id from device
+ * read user device id from device
  */
-static int pcan_usb_get_device_id(struct peak_usb_device *dev, u32 *device_id)
+static int pcan_usb_get_user_devid(struct peak_usb_device *dev, u32 *user_devid)
 {
 	u8 args[PCAN_USB_CMD_ARGS_LEN];
 	int err;
@@ -393,7 +393,7 @@ static int pcan_usb_get_device_id(struct peak_usb_device *dev, u32 *device_id)
 		netdev_err(dev->netdev, "getting device id failure: %d\n", err);
 
 	else
-		*device_id = args[0];
+		*user_devid = args[0];
 
 	return err;
 }
@@ -1017,7 +1017,7 @@ const struct peak_usb_adapter pcan_usb = {
 	.dev_init = pcan_usb_init,
 	.dev_set_bus = pcan_usb_write_mode,
 	.dev_set_bittiming = pcan_usb_set_bittiming,
-	.dev_get_device_id = pcan_usb_get_device_id,
+	.dev_get_user_devid = pcan_usb_get_user_devid,
 	.dev_decode_buf = pcan_usb_decode_buf,
 	.dev_encode_msg = pcan_usb_encode_msg,
 	.dev_start = pcan_usb_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 225697d70a9a..8e1b3c19f92f 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -922,11 +922,11 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	}
 
 	/* get device number early */
-	if (dev->adapter->dev_get_device_id)
-		dev->adapter->dev_get_device_id(dev, &dev->device_number);
+	if (dev->adapter->dev_get_user_devid)
+		dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
 
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
-			peak_usb_adapter->name, ctrl_idx, dev->device_number);
+			peak_usb_adapter->name, ctrl_idx, dev->user_devid);
 
 	return 0;
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index f6bdd8b3f290..6ff32673a256 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -60,7 +60,7 @@ struct peak_usb_adapter {
 	int (*dev_set_data_bittiming)(struct peak_usb_device *dev,
 				      struct can_bittiming *bt);
 	int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff);
-	int (*dev_get_device_id)(struct peak_usb_device *dev, u32 *device_id);
+	int (*dev_get_user_devid)(struct peak_usb_device *dev, u32 *user_devid);
 	int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb);
 	int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb,
 					u8 *obuf, size_t *size);
@@ -122,7 +122,7 @@ struct peak_usb_device {
 	u8 *cmd_buf;
 	struct usb_anchor rx_submitted;
 
-	u32 device_number;
+	u32 user_devid;
 	u8 device_rev;
 
 	u8 ep_msg_in;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 2ea1500df393..b8053e697261 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -972,7 +972,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
 	}
 
 	pdev->usb_if->dev[dev->ctrl_idx] = dev;
-	dev->device_number =
+	dev->user_devid =
 		le32_to_cpu(pdev->usb_if->fw_info.dev_id[dev->ctrl_idx]);
 
 	/* if vendor rsp is of type 2, then it contains EP numbers to
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 5d8f6a40bb2c..15410d60cdf7 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -419,8 +419,8 @@ static int pcan_usb_pro_set_led(struct peak_usb_device *dev, u8 mode,
 	return pcan_usb_pro_send_cmd(dev, &um);
 }
 
-static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
-				      u32 *device_id)
+static int pcan_usb_pro_get_user_devid(struct peak_usb_device *dev,
+				       u32 *user_devid)
 {
 	struct pcan_usb_pro_devid *pdn;
 	struct pcan_usb_pro_msg um;
@@ -439,7 +439,7 @@ static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
 		return err;
 
 	pdn = (struct pcan_usb_pro_devid *)pc;
-	*device_id = le32_to_cpu(pdn->dev_num);
+	*user_devid = le32_to_cpu(pdn->dev_num);
 
 	return err;
 }
@@ -1076,7 +1076,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	.dev_free = pcan_usb_pro_free,
 	.dev_set_bus = pcan_usb_pro_set_bus,
 	.dev_set_bittiming = pcan_usb_pro_set_bittiming,
-	.dev_get_device_id = pcan_usb_pro_get_device_id,
+	.dev_get_user_devid = pcan_usb_pro_get_user_devid,
 	.dev_decode_buf = pcan_usb_pro_decode_buf,
 	.dev_encode_msg = pcan_usb_pro_encode_msg,
 	.dev_start = pcan_usb_pro_start,
-- 
2.37.2


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

* [PATCH v2 2/7] can: peak_usb: add callback to read user value of CANFD devices
  2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 1/7] can: peak_usb: rename device_id to a more explicit name Lukas Magel
@ 2022-10-30 10:59   ` Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 3/7] can: peak_usb: allow flashing of the user device id Lukas Magel
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-30 10:59 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch adds the specific function that allows to read a user defined
value from the non volatile memory of the USB CANFD interfaces of
PEAK-System.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c |  3 +-
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 33 +++++++++++++++++---
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 8e1b3c19f92f..ca282b0aa9a5 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -922,8 +922,7 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	}
 
 	/* get device number early */
-	if (dev->adapter->dev_get_user_devid)
-		dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
+	dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
 
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
 			peak_usb_adapter->name, ctrl_idx, dev->user_devid);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index b8053e697261..2db358d0295e 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -234,6 +234,15 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
 	return err;
 }
 
+static int pcan_usb_fd_read_fwinfo(struct peak_usb_device *dev,
+				   struct pcan_ufd_fw_info *fw_info)
+{
+	return pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
+				     PCAN_USBPRO_INFO_FW,
+				     fw_info,
+				     sizeof(*fw_info));
+}
+
 /* build the commands list in the given buffer, to enter operational mode */
 static int pcan_usb_fd_build_restart_cmd(struct peak_usb_device *dev, u8 *buf)
 {
@@ -434,6 +443,21 @@ static int pcan_usb_fd_set_bittiming_fast(struct peak_usb_device *dev,
 	return pcan_usb_fd_send_cmd(dev, ++cmd);
 }
 
+/* read user device id from device */
+static int pcan_usb_fd_get_user_devid(struct peak_usb_device *dev,
+				      u32 *user_devid)
+{
+	int err;
+	struct pcan_usb_fd_if *usb_if = pcan_usb_fd_dev_if(dev);
+
+	err = pcan_usb_fd_read_fwinfo(dev, &usb_if->fw_info);
+	if (err)
+		return err;
+
+	*user_devid = le32_to_cpu(usb_if->fw_info.dev_id[dev->ctrl_idx]);
+	return err;
+}
+
 /* handle restart but in asynchronously way
  * (uses PCAN-USB Pro code to complete asynchronous request)
  */
@@ -907,10 +931,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
 
 		fw_info = &pdev->usb_if->fw_info;
 
-		err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
-					    PCAN_USBPRO_INFO_FW,
-					    fw_info,
-					    sizeof(*fw_info));
+		err = pcan_usb_fd_read_fwinfo(dev, fw_info);
 		if (err) {
 			dev_err(dev->netdev->dev.parent,
 				"unable to read %s firmware info (err %d)\n",
@@ -1148,6 +1169,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1222,6 +1244,7 @@ const struct peak_usb_adapter pcan_usb_chip = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1296,6 +1319,7 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1370,6 +1394,7 @@ const struct peak_usb_adapter pcan_usb_x6 = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
-- 
2.37.2


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

* [PATCH v2 3/7] can: peak_usb: allow flashing of the user device id
  2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 1/7] can: peak_usb: rename device_id to a more explicit name Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 2/7] can: peak_usb: add callback to read user value of CANFD devices Lukas Magel
@ 2022-10-30 10:59   ` Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-30 10:59 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This series of patches adds a callback that allows the user to flash a
self-defined device id to all USB - CAN/CANFD interfaces of PEAK-System
managed by this driver, namely:
- PCAN-USB
- PCAN-USB FD
- PCAN-USB Pro FD
- PCAN-USB X6
- PCAN-Chip USB
- PCAN-USB Pro

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      | 26 ++++++++++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 26 ++++++++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  | 15 +++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.h  |  1 +
 5 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 11fd033b57f3..6c01b2c6212b 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -9,10 +9,12 @@
  * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
  */
 #include <asm/unaligned.h>
+
+#include <linux/ethtool.h>
+#include <linux/limits.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -398,6 +400,25 @@ static int pcan_usb_get_user_devid(struct peak_usb_device *dev, u32 *user_devid)
 	return err;
 }
 
+/* set a new user device id in the flash memory of the device */
+static int pcan_usb_set_user_devid(struct peak_usb_device *dev, u32 user_devid)
+{
+	u8 args[PCAN_USB_CMD_ARGS_LEN];
+
+	/* this kind of device supports 8-bit values only */
+	if (user_devid > U8_MAX)
+		return -EINVAL;
+
+	/* during the flash process the device disconnects during ~1.25 s.:
+	 * prohibit access when interface is UP
+	 */
+	if (dev->netdev->flags & IFF_UP)
+		return -EBUSY;
+
+	args[0] = user_devid;
+	return pcan_usb_send_cmd(dev, PCAN_USB_CMD_DEVID, PCAN_USB_SET, args);
+}
+
 /*
  * update current time ref with received timestamp
  */
@@ -1018,6 +1039,7 @@ const struct peak_usb_adapter pcan_usb = {
 	.dev_set_bus = pcan_usb_write_mode,
 	.dev_set_bittiming = pcan_usb_set_bittiming,
 	.dev_get_user_devid = pcan_usb_get_user_devid,
+	.dev_set_user_devid = pcan_usb_set_user_devid,
 	.dev_decode_buf = pcan_usb_decode_buf,
 	.dev_encode_msg = pcan_usb_encode_msg,
 	.dev_start = pcan_usb_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 6ff32673a256..d9c9e333c47a 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -61,6 +61,7 @@ struct peak_usb_adapter {
 				      struct can_bittiming *bt);
 	int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff);
 	int (*dev_get_user_devid)(struct peak_usb_device *dev, u32 *user_devid);
+	int (*dev_set_user_devid)(struct peak_usb_device *dev, u32 user_devid);
 	int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb);
 	int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb,
 					u8 *obuf, size_t *size);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 2db358d0295e..1f5ad0dc2b1c 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -147,6 +147,15 @@ struct __packed pcan_ufd_ovr_msg {
 	u8	unused[3];
 };
 
+#define PCAN_UFD_CMD_DEVID_SET		0x81
+
+struct __packed pcan_ufd_device_id {
+	__le16	opcode_channel;
+
+	u16	unused;
+	__le32	device_id;
+};
+
 static inline int pufd_omsg_get_channel(struct pcan_ufd_ovr_msg *om)
 {
 	return om->channel & 0xf;
@@ -458,6 +467,19 @@ static int pcan_usb_fd_get_user_devid(struct peak_usb_device *dev,
 	return err;
 }
 
+/* set a new user device id in the flash memory of the device */
+static int pcan_usb_fd_set_user_devid(struct peak_usb_device *dev, u32 devid)
+{
+	struct pcan_ufd_device_id *cmd = pcan_usb_fd_cmd_buffer(dev);
+
+	cmd->opcode_channel = pucan_cmd_opcode_channel(dev->ctrl_idx,
+						       PCAN_UFD_CMD_DEVID_SET);
+	cmd->device_id = cpu_to_le32(devid);
+
+	/* send the command */
+	return pcan_usb_fd_send_cmd(dev, ++cmd);
+}
+
 /* handle restart but in asynchronously way
  * (uses PCAN-USB Pro code to complete asynchronous request)
  */
@@ -1170,6 +1192,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
+	.dev_set_user_devid = pcan_usb_fd_set_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1245,6 +1268,7 @@ const struct peak_usb_adapter pcan_usb_chip = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
+	.dev_set_user_devid = pcan_usb_fd_set_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1320,6 +1344,7 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
+	.dev_set_user_devid = pcan_usb_fd_set_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1395,6 +1420,7 @@ const struct peak_usb_adapter pcan_usb_x6 = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_user_devid = pcan_usb_fd_get_user_devid,
+	.dev_set_user_devid = pcan_usb_fd_set_user_devid,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 15410d60cdf7..d3731c5aa4ed 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -76,6 +76,7 @@ static u16 pcan_usb_pro_sizeof_rec[256] = {
 	[PCAN_USBPRO_SETFILTR] = sizeof(struct pcan_usb_pro_filter),
 	[PCAN_USBPRO_SETTS] = sizeof(struct pcan_usb_pro_setts),
 	[PCAN_USBPRO_GETDEVID] = sizeof(struct pcan_usb_pro_devid),
+	[PCAN_USBPRO_SETDEVID] = sizeof(struct pcan_usb_pro_devid),
 	[PCAN_USBPRO_SETLED] = sizeof(struct pcan_usb_pro_setled),
 	[PCAN_USBPRO_RXMSG8] = sizeof(struct pcan_usb_pro_rxmsg),
 	[PCAN_USBPRO_RXMSG4] = sizeof(struct pcan_usb_pro_rxmsg) - 4,
@@ -149,6 +150,7 @@ static int pcan_msg_add_rec(struct pcan_usb_pro_msg *pm, int id, ...)
 
 	case PCAN_USBPRO_SETBTR:
 	case PCAN_USBPRO_GETDEVID:
+	case PCAN_USBPRO_SETDEVID:
 		*pc++ = va_arg(ap, int);
 		pc += 2;
 		*(__le32 *)pc = cpu_to_le32(va_arg(ap, u32));
@@ -444,6 +446,18 @@ static int pcan_usb_pro_get_user_devid(struct peak_usb_device *dev,
 	return err;
 }
 
+static int pcan_usb_pro_set_user_devid(struct peak_usb_device *dev,
+				       u32 user_devid)
+{
+	struct pcan_usb_pro_msg um;
+
+	pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+	pcan_msg_add_rec(&um, PCAN_USBPRO_SETDEVID, dev->ctrl_idx,
+			 user_devid);
+
+	return pcan_usb_pro_send_cmd(dev, &um);
+}
+
 static int pcan_usb_pro_set_bittiming(struct peak_usb_device *dev,
 				      struct can_bittiming *bt)
 {
@@ -1077,6 +1091,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	.dev_set_bus = pcan_usb_pro_set_bus,
 	.dev_set_bittiming = pcan_usb_pro_set_bittiming,
 	.dev_get_user_devid = pcan_usb_pro_get_user_devid,
+	.dev_set_user_devid = pcan_usb_pro_set_user_devid,
 	.dev_decode_buf = pcan_usb_pro_decode_buf,
 	.dev_encode_msg = pcan_usb_pro_encode_msg,
 	.dev_start = pcan_usb_pro_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
index a34e0fc021c9..28e740af905d 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
@@ -62,6 +62,7 @@ struct __packed pcan_usb_pro_fwinfo {
 #define PCAN_USBPRO_SETBTR	0x02
 #define PCAN_USBPRO_SETBUSACT	0x04
 #define PCAN_USBPRO_SETSILENT	0x05
+#define PCAN_USBPRO_SETDEVID	0x06
 #define PCAN_USBPRO_SETFILTR	0x0a
 #define PCAN_USBPRO_SETTS	0x10
 #define PCAN_USBPRO_GETDEVID	0x12
-- 
2.37.2


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

* [PATCH v2 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev()
  2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                     ` (2 preceding siblings ...)
  2022-10-30 10:59   ` [PATCH v2 3/7] can: peak_usb: allow flashing of the user device id Lukas Magel
@ 2022-10-30 10:59   ` Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 5/7] can: peak_usb: add ethtool interface to user defined flashed device number Lukas Magel
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-30 10:59 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch changes call to unregister_netdev() with unregister_candev().

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index ca282b0aa9a5..b010b546f6d1 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -963,7 +963,7 @@ static void peak_usb_disconnect(struct usb_interface *intf)
 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
 		strscpy(name, netdev->name, IFNAMSIZ);
 
-		unregister_netdev(netdev);
+		unregister_candev(netdev);
 
 		kfree(dev->cmd_buf);
 		dev->next_siblings = NULL;
-- 
2.37.2


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

* [PATCH v2 5/7] can: peak_usb: add ethtool interface to user defined flashed device number
  2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                     ` (3 preceding siblings ...)
  2022-10-30 10:59   ` [PATCH v2 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
@ 2022-10-30 10:59   ` Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 7/7] can: peak_usb: align user device id format in log with sysfs attribute Lukas Magel
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-30 10:59 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch introduces 3 new functions implementing support for eeprom
access of USB - CAN network interfaces managed by the driver, through the
ethtool interface. All of them (except the PCAN-USB interface) interpret
the 4 data bytes as a 32-bit value to be read/write in the non-volatile
memory of the device. The PCAN-USB only manages a single byte value.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      |  9 +++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 80 ++++++++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  6 ++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  3 +
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  3 +
 5 files changed, 101 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 6c01b2c6212b..d205da827016 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -984,9 +984,18 @@ static int pcan_usb_set_phys_id(struct net_device *netdev,
 	return err;
 }
 
+/* This device only handles 8-bit user device id. */
+static int pcan_usb_get_eeprom_len(struct net_device *netdev)
+{
+	return sizeof(u8);
+}
+
 static const struct ethtool_ops pcan_usb_ethtool_ops = {
 	.set_phys_id = pcan_usb_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= pcan_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /*
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index b010b546f6d1..d8af448058fa 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -808,6 +808,86 @@ static const struct net_device_ops peak_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+/* CAN-USB devices generally handle 32-bit user device id.
+ * In case one doesn't, then it have to overload this function.
+ */
+int peak_usb_get_eeprom_len(struct net_device *netdev)
+{
+	return sizeof(u32);
+}
+
+/* Every CAN-USB device exports the dev_get_user_devid() operation. It is used
+ * here to fill the data buffer with the user defined device number.
+ */
+int peak_usb_get_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct peak_usb_device *dev = netdev_priv(netdev);
+	u32 devid;
+	__le32 devid_le;
+	int err;
+
+	err = dev->adapter->dev_get_user_devid(dev, &devid);
+	if (err)
+		return err;
+
+	/* ethtool operates on individual bytes. The byte order of the user
+	 * device id in memory depends on the kernel architecture. We
+	 * convert the user device id back to the native byte order of the PEAK
+	 * device itself to ensure that the order is consistent for all
+	 * host architectures.
+	 */
+	devid_le = cpu_to_le32(devid);
+	memcpy(data, (u8 *)&devid_le + eeprom->offset, eeprom->len);
+
+	/* update cached value */
+	dev->user_devid = devid;
+	return err;
+}
+
+/* Every CAN-USB device exports the dev_get_user_devid()/dev_set_user_devid()
+ * operations. They are used here to set the new user defined device number.
+ */
+int peak_usb_set_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct peak_usb_device *dev = netdev_priv(netdev);
+	u32 devid;
+	__le32 devid_le;
+	int err;
+
+	/* first, read the current user defined device value number */
+	err = dev->adapter->dev_get_user_devid(dev, &devid);
+	if (err) {
+		netdev_err(netdev, "Failed to init device id (err %d)\n", err);
+		return err;
+	}
+
+	/* do update the value with user given bytes.
+	 * ethtool operates on individual bytes. The byte order of the user
+	 * device id in memory depends on the kernel architecture. We
+	 * convert the user device id back to the native byte order of the PEAK
+	 * device itself to ensure that the order is consistent for all
+	 * host architectures.
+	 */
+	devid_le = cpu_to_le32(devid);
+	memcpy((u8 *)&devid_le + eeprom->offset, data, eeprom->len);
+	devid = le32_to_cpu(devid_le);
+
+	/* flash the new value now */
+	err = dev->adapter->dev_set_user_devid(dev, devid);
+	if (err) {
+		netdev_err(netdev, "Failed to write new device id (err %d)\n",
+			   err);
+		return err;
+	}
+
+	/* update cached value with the new one */
+	dev->user_devid = devid;
+
+	return 0;
+}
+
 int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
 {
 	info->so_timestamping =
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index d9c9e333c47a..a4a43edc0456 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -148,4 +148,10 @@ void peak_usb_async_complete(struct urb *urb);
 void peak_usb_restart_complete(struct peak_usb_device *dev);
 int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
 
+/* common 32-bit devid ethtool management */
+int peak_usb_get_eeprom_len(struct net_device *netdev);
+int peak_usb_get_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data);
+int peak_usb_set_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data);
 #endif
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 1f5ad0dc2b1c..5188915c4299 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1124,6 +1124,9 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
 	.set_phys_id = pcan_usb_fd_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= peak_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /* describes the PCAN-USB FD adapter */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index d3731c5aa4ed..d45e6562a4bb 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -1037,6 +1037,9 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
 	.set_phys_id = pcan_usb_pro_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= peak_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /*
-- 
2.37.2


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

* [PATCH v2 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute
  2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                     ` (4 preceding siblings ...)
  2022-10-30 10:59   ` [PATCH v2 5/7] can: peak_usb: add ethtool interface to user defined flashed device number Lukas Magel
@ 2022-10-30 10:59   ` Lukas Magel
  2022-10-30 10:59   ` [PATCH v2 7/7] can: peak_usb: align user device id format in log with sysfs attribute Lukas Magel
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-30 10:59 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel, Stephane Grosjean

This patch exports the user device ID as a sysfs attribute. This allows
users to easily read the ID and to write udev rules that can match against
the ID.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 .../ABI/testing/sysfs-class-net-peak_usb      | 15 ++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c  | 30 +++++++++++++++++--
 2 files changed, 42 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-peak_usb

diff --git a/Documentation/ABI/testing/sysfs-class-net-peak_usb b/Documentation/ABI/testing/sysfs-class-net-peak_usb
new file mode 100644
index 000000000000..f7f23f9bdfde
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-peak_usb
@@ -0,0 +1,15 @@
+
+What:		/sys/class/net/<iface>/peak_usb/user_devid
+Date:		October 2022
+KernelVersion:	6.1
+Contact:	Stephane Grosjean <s.grosjean@peak-system.com>
+Description:
+		PEAK PCAN-USB devices support a user-configurable device
+		identifier. This attribute provides read-only access to the
+		currently configured value of the device identifier. Depending
+		on the device type, the identifier has a length of 8 or 32 bit.
+		The value read from this attribute is always an 8 digit 32 bit
+		hexadecimal value in big endian format. If the device only
+		supports an 8 bit identifier, the upper 24 bit of the value are
+		set to zero.
+
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index d8af448058fa..e558746a0252 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -8,13 +8,15 @@
  *
  * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
  */
+#include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/init.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
 #include <linux/usb.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -53,6 +55,25 @@ static const struct usb_device_id peak_usb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, peak_usb_table);
 
+static ssize_t user_devid_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct net_device *netdev = to_net_dev(dev);
+	struct peak_usb_device *peak_dev = netdev_priv(netdev);
+
+	return sysfs_emit(buf, "%08X\n", peak_dev->user_devid);
+}
+static DEVICE_ATTR_RO(user_devid);
+
+static const struct attribute *peak_usb_sysfs_attrs[] = {
+	&dev_attr_user_devid.attr,
+	NULL,
+};
+
+static const struct attribute_group peak_usb_sysfs_group = {
+	.name	= "peak_usb",
+	.attrs	= (struct attribute **)peak_usb_sysfs_attrs,
+};
+
 /*
  * dump memory
  */
@@ -961,6 +982,9 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	/* add ethtool support */
 	netdev->ethtool_ops = peak_usb_adapter->ethtool_ops;
 
+	/* register peak_usb sysfs files */
+	netdev->sysfs_groups[0] = &peak_usb_sysfs_group;
+
 	init_usb_anchor(&dev->rx_submitted);
 
 	init_usb_anchor(&dev->tx_submitted);
-- 
2.37.2


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

* [PATCH v2 7/7] can: peak_usb: align user device id format in log with sysfs attribute
  2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
                     ` (5 preceding siblings ...)
  2022-10-30 10:59   ` [PATCH v2 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute Lukas Magel
@ 2022-10-30 10:59   ` Lukas Magel
  6 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-10-30 10:59 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel

Previously, the user device id was printed to the kernel log in decimal
upon connecting a new PEAK device. This behavior is inconsistent with
the hexadecimal format of the user device id sysfs attribute. This patch
updates the log message to output the id in hexadecimal.

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index e558746a0252..731bd6553cfc 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -1028,8 +1028,8 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	/* get device number early */
 	dev->adapter->dev_get_user_devid(dev, &dev->user_devid);
 
-	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
-			peak_usb_adapter->name, ctrl_idx, dev->user_devid);
+	netdev_info(netdev, "attached to %s channel %u (device %08Xh)\n",
+		    peak_usb_adapter->name, ctrl_idx, dev->user_devid);
 
 	return 0;
 
-- 
2.37.2


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

* [PATCH v3 0/7] can: peak_usb: Introduce configurable CAN channel ID
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (3 preceding siblings ...)
  2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
@ 2022-12-13  8:03 ` Lukas Magel
  2022-12-13  8:03 ` [PATCH v3 1/8] can: peak_usb: rename device_id to " Lukas Magel
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-12-13  8:03 UTC (permalink / raw)
  To: linux-can

This series of patches introduces the CAN channel ID for the PEAK USB
CAN interfaces. The id can be read/written via ethtool and is exposed as
a read-only attribute via sysfs. This allows users to set the id via
ethtool and write udev rules to match against the sysfs attribute.

Part of the patches were originally introduced by Stéphane Grosjean and
were modified slightly. See the following threads for the original patches:

* https://lore.kernel.org/linux-can/20220128150157.1222850-1-s.grosjean@peak-system.com/T/#mad8014c9f1c89a50d5944a50ae0a585edec79eab
* https://lore.kernel.org/linux-can/20211117150132.37056-1-s.grosjean@peak-system.com/T/#mbf1d7db8433734a1fe08868d79f9927a04fe7ffe

v3:
* Fix the issues raised on netdev
* Rename user device ID to CAN channel ID to make the 1-to-N mapping
  between USB device and exposed CAN channels more obvious

v2:
* Fix type of devid_le in ethtool peak_usb_(get|set)_eeprom
* Fix signed-off tags

Stéphane Grosjean (5):
  can: peak_usb: rename device_id to CAN channel ID
  can: peak_usb: add callback to read CAN channel ID of
  can: peak_usb: allow flashing of the CAN channel ID
  can: peak_usb: replace unregister_netdev() with
  can: peak_usb: add ethtool interface to

Lukas Magel (3):
  can: peak_usb: export PCAN CAN channel ID as sysfs
  can: peak_usb: align CAN channel ID format in log with
  can: peak_usb: Reorder include directives

.../ABI/testing/sysfs-class-net-peak_usb        |  19 +++
 drivers/net/can/usb/peak_usb/pcan_usb.c         |  45 +++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.c    | 122 +++++++++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h    |  12 +-
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c      |  68 +++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c     |  30 ++++-
 drivers/net/can/usb/peak_usb/pcan_usb_pro.h     |   1 +
 7 files changed, 266 insertions(+), 31 deletions(-)




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

* [PATCH v3 1/8] can: peak_usb: rename device_id to CAN channel ID
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (4 preceding siblings ...)
  2022-12-13  8:03 ` [PATCH v3 0/7] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
@ 2022-12-13  8:03 ` Lukas Magel
  2022-12-13  8:03 ` [PATCH v3 2/8] can: peak_usb: add callback to read CAN channel ID of PEAK CAN-FD devices Lukas Magel
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-12-13  8:03 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

The so-called "device id" is a user-defined identifier value that can be
set individually for each CAN interface of a PEAK USB device.
Contrary to a static serial number, the value can be changed by the
user. With this ID, each CAN interface can be uniquely identified even if
the USB device does not export a proper serial number or the USB device
exports multiple CAN interfaces. In order to not confuse it with the
device ID used by the USB core and emphasize the link to the CAN
interface, the functions and variables for reading this user-defined
value are renamed to CAN channel ID.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      | 10 +++++-----
 drivers/net/can/usb/peak_usb/pcan_usb_core.c |  8 ++++----
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  5 +++--
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  2 +-
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  8 ++++----
 5 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 687dd542f7f6..7b3282e5c880 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -381,19 +381,19 @@ static int pcan_usb_get_serial(struct peak_usb_device *dev, u32 *serial_number)
 }
 
 /*
- * read device id from device
+ * read can channel id from device
  */
-static int pcan_usb_get_device_id(struct peak_usb_device *dev, u32 *device_id)
+static int pcan_usb_get_can_channel_id(struct peak_usb_device *dev, u32 *can_ch_id)
 {
 	u8 args[PCAN_USB_CMD_ARGS_LEN];
 	int err;
 
 	err = pcan_usb_wait_rsp(dev, PCAN_USB_CMD_DEVID, PCAN_USB_GET, args);
 	if (err)
-		netdev_err(dev->netdev, "getting device id failure: %d\n", err);
+		netdev_err(dev->netdev, "getting can channel id failure: %d\n", err);
 
 	else
-		*device_id = args[0];
+		*can_ch_id = args[0];
 
 	return err;
 }
@@ -1017,7 +1017,7 @@ const struct peak_usb_adapter pcan_usb = {
 	.dev_init = pcan_usb_init,
 	.dev_set_bus = pcan_usb_write_mode,
 	.dev_set_bittiming = pcan_usb_set_bittiming,
-	.dev_get_device_id = pcan_usb_get_device_id,
+	.dev_get_can_channel_id = pcan_usb_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_decode_buf,
 	.dev_encode_msg = pcan_usb_encode_msg,
 	.dev_start = pcan_usb_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 225697d70a9a..a3a25a2e8d41 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -921,12 +921,12 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 			goto adap_dev_free;
 	}
 
-	/* get device number early */
-	if (dev->adapter->dev_get_device_id)
-		dev->adapter->dev_get_device_id(dev, &dev->device_number);
+	/* get CAN channel id early */
+	if (dev->adapter->dev_get_can_channel_id)
+		dev->adapter->dev_get_can_channel_id(dev, &dev->can_channel_id);
 
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
-			peak_usb_adapter->name, ctrl_idx, dev->device_number);
+			peak_usb_adapter->name, ctrl_idx, dev->can_channel_id);
 
 	return 0;
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index f6bdd8b3f290..6de0429c268f 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -60,7 +60,7 @@ struct peak_usb_adapter {
 	int (*dev_set_data_bittiming)(struct peak_usb_device *dev,
 				      struct can_bittiming *bt);
 	int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff);
-	int (*dev_get_device_id)(struct peak_usb_device *dev, u32 *device_id);
+	int (*dev_get_can_channel_id)(struct peak_usb_device *dev, u32 *can_ch_id);
 	int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb);
 	int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb,
 					u8 *obuf, size_t *size);
@@ -122,7 +122,8 @@ struct peak_usb_device {
 	u8 *cmd_buf;
 	struct usb_anchor rx_submitted;
 
-	u32 device_number;
+	/* equivalent to the device ID in the Windows API */
+	u32 can_channel_id;
 	u8 device_rev;
 
 	u8 ep_msg_in;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 2ea1500df393..2e0955900ebe 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -972,7 +972,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
 	}
 
 	pdev->usb_if->dev[dev->ctrl_idx] = dev;
-	dev->device_number =
+	dev->can_channel_id =
 		le32_to_cpu(pdev->usb_if->fw_info.dev_id[dev->ctrl_idx]);
 
 	/* if vendor rsp is of type 2, then it contains EP numbers to
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 5d8f6a40bb2c..3a13cfef47bb 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -419,8 +419,8 @@ static int pcan_usb_pro_set_led(struct peak_usb_device *dev, u8 mode,
 	return pcan_usb_pro_send_cmd(dev, &um);
 }
 
-static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
-				      u32 *device_id)
+static int pcan_usb_pro_get_can_channel_id(struct peak_usb_device *dev,
+					   u32 *can_ch_id)
 {
 	struct pcan_usb_pro_devid *pdn;
 	struct pcan_usb_pro_msg um;
@@ -439,7 +439,7 @@ static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
 		return err;
 
 	pdn = (struct pcan_usb_pro_devid *)pc;
-	*device_id = le32_to_cpu(pdn->dev_num);
+	*can_ch_id = le32_to_cpu(pdn->dev_num);
 
 	return err;
 }
@@ -1076,7 +1076,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	.dev_free = pcan_usb_pro_free,
 	.dev_set_bus = pcan_usb_pro_set_bus,
 	.dev_set_bittiming = pcan_usb_pro_set_bittiming,
-	.dev_get_device_id = pcan_usb_pro_get_device_id,
+	.dev_get_can_channel_id = pcan_usb_pro_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_pro_decode_buf,
 	.dev_encode_msg = pcan_usb_pro_encode_msg,
 	.dev_start = pcan_usb_pro_start,
-- 
2.38.1


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

* [PATCH v3 2/8] can: peak_usb: add callback to read CAN channel ID of PEAK CAN-FD devices
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (5 preceding siblings ...)
  2022-12-13  8:03 ` [PATCH v3 1/8] can: peak_usb: rename device_id to " Lukas Magel
@ 2022-12-13  8:03 ` Lukas Magel
  2022-12-13  8:03 ` [PATCH v3 3/8] can: peak_usb: allow flashing of the CAN channel ID Lukas Magel
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-12-13  8:03 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch adds a new function that allows to read the CAN channel ID
from the non volatile memory of the USB CAN-FD PEAK devices. The CAN
channel ID is a user-configurable u8/u32 identifier value that can be set
individually for each PEAK CAN interface.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c |  3 +-
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 33 +++++++++++++++++---
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index a3a25a2e8d41..54e2481cce30 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -922,8 +922,7 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	}
 
 	/* get CAN channel id early */
-	if (dev->adapter->dev_get_can_channel_id)
-		dev->adapter->dev_get_can_channel_id(dev, &dev->can_channel_id);
+	dev->adapter->dev_get_can_channel_id(dev, &dev->can_channel_id);
 
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
 			peak_usb_adapter->name, ctrl_idx, dev->can_channel_id);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 2e0955900ebe..a70ef0c7a800 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -234,6 +234,15 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
 	return err;
 }
 
+static int pcan_usb_fd_read_fwinfo(struct peak_usb_device *dev,
+				   struct pcan_ufd_fw_info *fw_info)
+{
+	return pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
+				     PCAN_USBPRO_INFO_FW,
+				     fw_info,
+				     sizeof(*fw_info));
+}
+
 /* build the commands list in the given buffer, to enter operational mode */
 static int pcan_usb_fd_build_restart_cmd(struct peak_usb_device *dev, u8 *buf)
 {
@@ -434,6 +443,21 @@ static int pcan_usb_fd_set_bittiming_fast(struct peak_usb_device *dev,
 	return pcan_usb_fd_send_cmd(dev, ++cmd);
 }
 
+/* read user CAN channel id from device */
+static int pcan_usb_fd_get_can_channel_id(struct peak_usb_device *dev,
+					  u32 *can_ch_id)
+{
+	int err;
+	struct pcan_usb_fd_if *usb_if = pcan_usb_fd_dev_if(dev);
+
+	err = pcan_usb_fd_read_fwinfo(dev, &usb_if->fw_info);
+	if (err)
+		return err;
+
+	*can_ch_id = le32_to_cpu(usb_if->fw_info.dev_id[dev->ctrl_idx]);
+	return err;
+}
+
 /* handle restart but in asynchronously way
  * (uses PCAN-USB Pro code to complete asynchronous request)
  */
@@ -907,10 +931,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
 
 		fw_info = &pdev->usb_if->fw_info;
 
-		err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
-					    PCAN_USBPRO_INFO_FW,
-					    fw_info,
-					    sizeof(*fw_info));
+		err = pcan_usb_fd_read_fwinfo(dev, fw_info);
 		if (err) {
 			dev_err(dev->netdev->dev.parent,
 				"unable to read %s firmware info (err %d)\n",
@@ -1148,6 +1169,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1222,6 +1244,7 @@ const struct peak_usb_adapter pcan_usb_chip = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1296,6 +1319,7 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1370,6 +1394,7 @@ const struct peak_usb_adapter pcan_usb_x6 = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
-- 
2.38.1


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

* [PATCH v3 3/8] can: peak_usb: allow flashing of the CAN channel ID
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (6 preceding siblings ...)
  2022-12-13  8:03 ` [PATCH v3 2/8] can: peak_usb: add callback to read CAN channel ID of PEAK CAN-FD devices Lukas Magel
@ 2022-12-13  8:03 ` Lukas Magel
  2022-12-13  8:03 ` [PATCH v3 4/8] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-12-13  8:03 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch adds callbacks that allow the user to set a new self-defined
CAN channel ID to all USB - CAN/CANFD interfaces of PEAK-System managed by
this driver, namely:
- PCAN-USB
- PCAN-USB FD
- PCAN-USB Pro FD
- PCAN-USB X6
- PCAN-Chip USB
- PCAN-USB Pro

The callback functions write the CAN channel ID to the non-volatile
memory of the devices.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      | 26 ++++++++++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 26 ++++++++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  | 15 +++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.h  |  1 +
 5 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 7b3282e5c880..92472149cfba 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -9,10 +9,12 @@
  * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
  */
 #include <asm/unaligned.h>
+
+#include <linux/ethtool.h>
+#include <linux/limits.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -398,6 +400,25 @@ static int pcan_usb_get_can_channel_id(struct peak_usb_device *dev, u32 *can_ch_
 	return err;
 }
 
+/* set a new CAN channel id in the flash memory of the device */
+static int pcan_usb_set_can_channel_id(struct peak_usb_device *dev, u32 can_ch_id)
+{
+	u8 args[PCAN_USB_CMD_ARGS_LEN];
+
+	/* this kind of device supports 8-bit values only */
+	if (can_ch_id > U8_MAX)
+		return -EINVAL;
+
+	/* during the flash process the device disconnects during ~1.25 s.:
+	 * prohibit access when interface is UP
+	 */
+	if (dev->netdev->flags & IFF_UP)
+		return -EBUSY;
+
+	args[0] = can_ch_id;
+	return pcan_usb_send_cmd(dev, PCAN_USB_CMD_DEVID, PCAN_USB_SET, args);
+}
+
 /*
  * update current time ref with received timestamp
  */
@@ -1018,6 +1039,7 @@ const struct peak_usb_adapter pcan_usb = {
 	.dev_set_bus = pcan_usb_write_mode,
 	.dev_set_bittiming = pcan_usb_set_bittiming,
 	.dev_get_can_channel_id = pcan_usb_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_decode_buf,
 	.dev_encode_msg = pcan_usb_encode_msg,
 	.dev_start = pcan_usb_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 6de0429c268f..1e461aef0f2a 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -61,6 +61,7 @@ struct peak_usb_adapter {
 				      struct can_bittiming *bt);
 	int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff);
 	int (*dev_get_can_channel_id)(struct peak_usb_device *dev, u32 *can_ch_id);
+	int (*dev_set_can_channel_id)(struct peak_usb_device *dev, u32 can_ch_id);
 	int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb);
 	int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb,
 					u8 *obuf, size_t *size);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index a70ef0c7a800..1ea4cfdfd640 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -147,6 +147,15 @@ struct __packed pcan_ufd_ovr_msg {
 	u8	unused[3];
 };
 
+#define PCAN_UFD_CMD_DEVID_SET		0x81
+
+struct __packed pcan_ufd_device_id {
+	__le16	opcode_channel;
+
+	u16	unused;
+	__le32	device_id;
+};
+
 static inline int pufd_omsg_get_channel(struct pcan_ufd_ovr_msg *om)
 {
 	return om->channel & 0xf;
@@ -458,6 +467,19 @@ static int pcan_usb_fd_get_can_channel_id(struct peak_usb_device *dev,
 	return err;
 }
 
+/* set a new CAN channel id in the flash memory of the device */
+static int pcan_usb_fd_set_can_channel_id(struct peak_usb_device *dev, u32 can_ch_id)
+{
+	struct pcan_ufd_device_id *cmd = pcan_usb_fd_cmd_buffer(dev);
+
+	cmd->opcode_channel = pucan_cmd_opcode_channel(dev->ctrl_idx,
+						       PCAN_UFD_CMD_DEVID_SET);
+	cmd->device_id = cpu_to_le32(can_ch_id);
+
+	/* send the command */
+	return pcan_usb_fd_send_cmd(dev, ++cmd);
+}
+
 /* handle restart but in asynchronously way
  * (uses PCAN-USB Pro code to complete asynchronous request)
  */
@@ -1170,6 +1192,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_fd_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1245,6 +1268,7 @@ const struct peak_usb_adapter pcan_usb_chip = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_fd_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1320,6 +1344,7 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_fd_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1395,6 +1420,7 @@ const struct peak_usb_adapter pcan_usb_x6 = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_fd_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 3a13cfef47bb..061f04c20f96 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -76,6 +76,7 @@ static u16 pcan_usb_pro_sizeof_rec[256] = {
 	[PCAN_USBPRO_SETFILTR] = sizeof(struct pcan_usb_pro_filter),
 	[PCAN_USBPRO_SETTS] = sizeof(struct pcan_usb_pro_setts),
 	[PCAN_USBPRO_GETDEVID] = sizeof(struct pcan_usb_pro_devid),
+	[PCAN_USBPRO_SETDEVID] = sizeof(struct pcan_usb_pro_devid),
 	[PCAN_USBPRO_SETLED] = sizeof(struct pcan_usb_pro_setled),
 	[PCAN_USBPRO_RXMSG8] = sizeof(struct pcan_usb_pro_rxmsg),
 	[PCAN_USBPRO_RXMSG4] = sizeof(struct pcan_usb_pro_rxmsg) - 4,
@@ -149,6 +150,7 @@ static int pcan_msg_add_rec(struct pcan_usb_pro_msg *pm, int id, ...)
 
 	case PCAN_USBPRO_SETBTR:
 	case PCAN_USBPRO_GETDEVID:
+	case PCAN_USBPRO_SETDEVID:
 		*pc++ = va_arg(ap, int);
 		pc += 2;
 		*(__le32 *)pc = cpu_to_le32(va_arg(ap, u32));
@@ -444,6 +446,18 @@ static int pcan_usb_pro_get_can_channel_id(struct peak_usb_device *dev,
 	return err;
 }
 
+static int pcan_usb_pro_set_can_channel_id(struct peak_usb_device *dev,
+					   u32 can_ch_id)
+{
+	struct pcan_usb_pro_msg um;
+
+	pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+	pcan_msg_add_rec(&um, PCAN_USBPRO_SETDEVID, dev->ctrl_idx,
+			 can_ch_id);
+
+	return pcan_usb_pro_send_cmd(dev, &um);
+}
+
 static int pcan_usb_pro_set_bittiming(struct peak_usb_device *dev,
 				      struct can_bittiming *bt)
 {
@@ -1077,6 +1091,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	.dev_set_bus = pcan_usb_pro_set_bus,
 	.dev_set_bittiming = pcan_usb_pro_set_bittiming,
 	.dev_get_can_channel_id = pcan_usb_pro_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_pro_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_pro_decode_buf,
 	.dev_encode_msg = pcan_usb_pro_encode_msg,
 	.dev_start = pcan_usb_pro_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
index a34e0fc021c9..28e740af905d 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
@@ -62,6 +62,7 @@ struct __packed pcan_usb_pro_fwinfo {
 #define PCAN_USBPRO_SETBTR	0x02
 #define PCAN_USBPRO_SETBUSACT	0x04
 #define PCAN_USBPRO_SETSILENT	0x05
+#define PCAN_USBPRO_SETDEVID	0x06
 #define PCAN_USBPRO_SETFILTR	0x0a
 #define PCAN_USBPRO_SETTS	0x10
 #define PCAN_USBPRO_GETDEVID	0x12
-- 
2.38.1


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

* [PATCH v3 4/8] can: peak_usb: replace unregister_netdev() with unregister_candev()
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (7 preceding siblings ...)
  2022-12-13  8:03 ` [PATCH v3 3/8] can: peak_usb: allow flashing of the CAN channel ID Lukas Magel
@ 2022-12-13  8:03 ` Lukas Magel
  2022-12-13  8:03 ` [PATCH v3 5/8] can: peak_usb: add ethtool interface to user-configurable CAN channel identifier Lukas Magel
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-12-13  8:03 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch changes the call to unregister_netdev() in
peak_usb_disconnect() with unregister_candev().

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 54e2481cce30..4eff4b4706b9 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -963,7 +963,7 @@ static void peak_usb_disconnect(struct usb_interface *intf)
 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
 		strscpy(name, netdev->name, IFNAMSIZ);
 
-		unregister_netdev(netdev);
+		unregister_candev(netdev);
 
 		kfree(dev->cmd_buf);
 		dev->next_siblings = NULL;
-- 
2.38.1


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

* [PATCH v3 5/8] can: peak_usb: add ethtool interface to user-configurable CAN channel identifier
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (8 preceding siblings ...)
  2022-12-13  8:03 ` [PATCH v3 4/8] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
@ 2022-12-13  8:03 ` Lukas Magel
  2022-12-13  8:03 ` [PATCH v3 6/8] can: peak_usb: export PCAN CAN channel ID as sysfs device attribute Lukas Magel
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-12-13  8:03 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch introduces 3 new functions implementing support for ethtool
access to the CAN channel ID of all USB CAN network interfaces managed by
the driver. With this patch, it is possible to read/write the CAN
channel ID from/to the EEPROM via the ethtool interface.

The CAN channel ID is a user-configurable device identifier that can be
set individually for each CAN interface of a PEAK USB device. Depending on
the device, the identifier has a length of 8 or 32 bit. The identifier
is stored in the non-volatile memory of the device.

The identifier of a CAN interface can be read/written as an 8 or 32 bit
byte string in native (little-endian) byte order, where the length depends
on the device type.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      |  9 +++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 80 ++++++++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  6 ++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  3 +
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  3 +
 5 files changed, 101 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 92472149cfba..5a712a2beb5a 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -984,9 +984,18 @@ static int pcan_usb_set_phys_id(struct net_device *netdev,
 	return err;
 }
 
+/* This device only handles 8-bit CAN channel id. */
+static int pcan_usb_get_eeprom_len(struct net_device *netdev)
+{
+	return sizeof(u8);
+}
+
 static const struct ethtool_ops pcan_usb_ethtool_ops = {
 	.set_phys_id = pcan_usb_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= pcan_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /*
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 4eff4b4706b9..d5ebcee7b7ed 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -808,6 +808,86 @@ static const struct net_device_ops peak_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+/* CAN-USB devices generally handle 32-bit CAN channel IDs.
+ * In case one doesn't, then it have to overload this function.
+ */
+int peak_usb_get_eeprom_len(struct net_device *netdev)
+{
+	return sizeof(u32);
+}
+
+/* Every CAN-USB device exports the dev_get_can_channel_id() operation. It is used
+ * here to fill the data buffer with the user defined CAN channel ID.
+ */
+int peak_usb_get_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct peak_usb_device *dev = netdev_priv(netdev);
+	u32 ch_id;
+	__le32 ch_id_le;
+	int err;
+
+	err = dev->adapter->dev_get_can_channel_id(dev, &ch_id);
+	if (err)
+		return err;
+
+	/* ethtool operates on individual bytes. The byte order of the CAN
+	 * channel id in memory depends on the kernel architecture. We
+	 * convert the CAN channel id back to the native byte order of the PEAK
+	 * device itself to ensure that the order is consistent for all
+	 * host architectures.
+	 */
+	ch_id_le = cpu_to_le32(ch_id);
+	memcpy(data, (u8 *)&ch_id_le + eeprom->offset, eeprom->len);
+
+	/* update cached value */
+	dev->can_channel_id = ch_id;
+	return err;
+}
+
+/* Every CAN-USB device exports the dev_get_can_channel_id()/dev_set_can_channel_id()
+ * operations. They are used here to set the new user defined CAN channel ID.
+ */
+int peak_usb_set_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct peak_usb_device *dev = netdev_priv(netdev);
+	u32 ch_id;
+	__le32 ch_id_le;
+	int err;
+
+	/* first, read the current user defined CAN channel ID */
+	err = dev->adapter->dev_get_can_channel_id(dev, &ch_id);
+	if (err) {
+		netdev_err(netdev, "Failed to init CAN channel id (err %d)\n", err);
+		return err;
+	}
+
+	/* do update the value with user given bytes.
+	 * ethtool operates on individual bytes. The byte order of the CAN
+	 * channel ID in memory depends on the kernel architecture. We
+	 * convert the CAN channel ID back to the native byte order of the PEAK
+	 * device itself to ensure that the order is consistent for all
+	 * host architectures.
+	 */
+	ch_id_le = cpu_to_le32(ch_id);
+	memcpy((u8 *)&ch_id_le + eeprom->offset, data, eeprom->len);
+	ch_id = le32_to_cpu(ch_id_le);
+
+	/* flash the new value now */
+	err = dev->adapter->dev_set_can_channel_id(dev, ch_id);
+	if (err) {
+		netdev_err(netdev, "Failed to write new CAN channel id (err %d)\n",
+			   err);
+		return err;
+	}
+
+	/* update cached value with the new one */
+	dev->can_channel_id = ch_id;
+
+	return 0;
+}
+
 int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
 {
 	info->so_timestamping =
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 1e461aef0f2a..980e315186cf 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -149,4 +149,10 @@ void peak_usb_async_complete(struct urb *urb);
 void peak_usb_restart_complete(struct peak_usb_device *dev);
 int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
 
+/* common 32-bit CAN channel ID ethtool management */
+int peak_usb_get_eeprom_len(struct net_device *netdev);
+int peak_usb_get_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data);
+int peak_usb_set_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data);
 #endif
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 1ea4cfdfd640..fd925ae96331 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1124,6 +1124,9 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
 	.set_phys_id = pcan_usb_fd_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= peak_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /* describes the PCAN-USB FD adapter */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 061f04c20f96..0c805d9672bf 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -1037,6 +1037,9 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
 	.set_phys_id = pcan_usb_pro_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= peak_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /*
-- 
2.38.1


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

* [PATCH v3 6/8] can: peak_usb: export PCAN CAN channel ID as sysfs device attribute
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (9 preceding siblings ...)
  2022-12-13  8:03 ` [PATCH v3 5/8] can: peak_usb: add ethtool interface to user-configurable CAN channel identifier Lukas Magel
@ 2022-12-13  8:03 ` Lukas Magel
  2022-12-13  8:03 ` [PATCH v3 7/8] can: peak_usb: align CAN channel ID format in log with sysfs attribute Lukas Magel
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-12-13  8:03 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel, Stephane Grosjean

This patch exports the CAN channel ID as a sysfs attribute. The CAN
channel ID is a user-configurable u8/u32 identifier that can be set
individually for each CAN interface of a PEAK USB device.

Exporting the channel ID as a sysfs attribute allows users to easily read
the ID and to write udev rules that can match against the ID. This is
especially useful for PEAK USB devices that do not export a serial
number at SUB level.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 .../ABI/testing/sysfs-class-net-peak_usb      | 19 ++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c  | 25 +++++++++++++++++++
 2 files changed, 44 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-peak_usb

diff --git a/Documentation/ABI/testing/sysfs-class-net-peak_usb b/Documentation/ABI/testing/sysfs-class-net-peak_usb
new file mode 100644
index 000000000000..9e3d0bf4d4b2
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-peak_usb
@@ -0,0 +1,19 @@
+
+What:		/sys/class/net/<iface>/peak_usb/can_channel_id
+Date:		November 2022
+KernelVersion:	6.2
+Contact:	Stephane Grosjean <s.grosjean@peak-system.com>
+Description:
+		PEAK PCAN-USB devices support user-configurable CAN channel
+		identifiers. Contrary to a USB serial number, these identifiers
+		are writable and can be set per CAN interface. This means that
+		if a USB device exports multiple CAN interfaces, each of them
+		can be assigned a unique channel ID.
+		This attribute provides read-only access to the currently
+		configured value of the channel identifier. Depending on the
+		device type, the identifier has a length of 8 or 32 bit. The
+		value read from this attribute is always an 8 digit 32 bit
+		hexadecimal value in big endian format. If the device only
+		supports an 8 bit identifier, the upper 24 bit of the value are
+		set to zero.
+
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index d5ebcee7b7ed..89ad5fda19c6 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -15,6 +15,8 @@
 #include <linux/netdevice.h>
 #include <linux/usb.h>
 #include <linux/ethtool.h>
+#include <linux/sysfs.h>
+#include <linux/device.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -53,6 +55,26 @@ static const struct usb_device_id peak_usb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, peak_usb_table);
 
+static ssize_t can_channel_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct net_device *netdev = to_net_dev(dev);
+	struct peak_usb_device *peak_dev = netdev_priv(netdev);
+
+	return sysfs_emit(buf, "%08X\n", peak_dev->can_channel_id);
+}
+static DEVICE_ATTR_RO(can_channel_id);
+
+/* mutable to avoid cast in attribute_group */
+static struct attribute *peak_usb_sysfs_attrs[] = {
+	&dev_attr_can_channel_id.attr,
+	NULL,
+};
+
+static const struct attribute_group peak_usb_sysfs_group = {
+	.name	= "peak_usb",
+	.attrs	= peak_usb_sysfs_attrs,
+};
+
 /*
  * dump memory
  */
@@ -961,6 +983,9 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	/* add ethtool support */
 	netdev->ethtool_ops = peak_usb_adapter->ethtool_ops;
 
+	/* register peak_usb sysfs files */
+	netdev->sysfs_groups[0] = &peak_usb_sysfs_group;
+
 	init_usb_anchor(&dev->rx_submitted);
 
 	init_usb_anchor(&dev->tx_submitted);
-- 
2.38.1


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

* [PATCH v3 7/8] can: peak_usb: align CAN channel ID format in log with sysfs attribute
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (10 preceding siblings ...)
  2022-12-13  8:03 ` [PATCH v3 6/8] can: peak_usb: export PCAN CAN channel ID as sysfs device attribute Lukas Magel
@ 2022-12-13  8:03 ` Lukas Magel
  2022-12-13  8:03 ` [PATCH v3 8/8] can: peak_usb: Reorder include directives alphabetically Lukas Magel
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
  13 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-12-13  8:03 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel

Previously, the CAN channel ID was printed to the kernel log in decimal
upon connecting a new PEAK device. This behavior is inconsistent with
the hexadecimal format of the CAN channel ID sysfs attribute. This patch
updates the log message to output the id in hexadecimal.

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 89ad5fda19c6..926d1359f433 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -1029,8 +1029,8 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	/* get CAN channel id early */
 	dev->adapter->dev_get_can_channel_id(dev, &dev->can_channel_id);
 
-	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
-			peak_usb_adapter->name, ctrl_idx, dev->can_channel_id);
+	netdev_info(netdev, "attached to %s channel %u (device 0x%08X)\n",
+		    peak_usb_adapter->name, ctrl_idx, dev->can_channel_id);
 
 	return 0;
 
-- 
2.38.1


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

* [PATCH v3 8/8] can: peak_usb: Reorder include directives alphabetically
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (11 preceding siblings ...)
  2022-12-13  8:03 ` [PATCH v3 7/8] can: peak_usb: align CAN channel ID format in log with sysfs attribute Lukas Magel
@ 2022-12-13  8:03 ` Lukas Magel
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
  13 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2022-12-13  8:03 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel

The include directives in all source files are reordered alphabetically
according to the names of the header files.

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 10 +++++-----
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  4 ++--
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 926d1359f433..f7305edc2784 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -8,15 +8,15 @@
  *
  * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
  */
+#include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/init.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
-#include <linux/usb.h>
-#include <linux/ethtool.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/device.h>
+#include <linux/usb.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index fd925ae96331..4d85b29a17b7 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -4,10 +4,10 @@
  *
  * Copyright (C) 2013-2014 Stephane Grosjean <s.grosjean@peak-system.com>
  */
+#include <linux/ethtool.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 0c805d9672bf..f736196383ac 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -6,10 +6,10 @@
  * Copyright (C) 2003-2011 PEAK System-Technik GmbH
  * Copyright (C) 2011-2012 Stephane Grosjean <s.grosjean@peak-system.com>
  */
+#include <linux/ethtool.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
-- 
2.38.1


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

* [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID
  2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
                   ` (12 preceding siblings ...)
  2022-12-13  8:03 ` [PATCH v3 8/8] can: peak_usb: Reorder include directives alphabetically Lukas Magel
@ 2023-01-16 20:09 ` Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 1/8] can: peak_usb: rename device_id to " Lukas Magel
                     ` (8 more replies)
  13 siblings, 9 replies; 48+ messages in thread
From: Lukas Magel @ 2023-01-16 20:09 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

This series of patches introduces the CAN channel ID for the PEAK USB
CAN interfaces. The id can be read/written via ethtool and is exposed as
a read-only attribute via sysfs. This allows users to set the id via
ethtool and write udev rules to match against the sysfs attribute.

Part of the patches were originally introduced by Stéphane Grosjean and
were modified. See the following threads for the original patches:

* https://lore.kernel.org/linux-can/20220128150157.1222850-1-s.grosjean@peak-system.com/T/#mad8014c9f1c89a50d5944a50ae0a585edec79eab
* https://lore.kernel.org/linux-can/20211117150132.37056-1-s.grosjean@peak-system.com/T/#mbf1d7db8433734a1fe08868d79f9927a04fe7ffe

v3:
* Fix the issues raised on netdev
* Rename user device ID to CAN channel ID to make the 1-to-N mapping
  between USB device and exposed CAN channels more obvious

v2:
* Fix type of devid_le in ethtool peak_usb_(get|set)_eeprom
* Fix signed-off tags

Stéphane Grosjean (5):
  can: peak_usb: rename device_id to CAN channel ID
  can: peak_usb: add callback to read CAN channel ID of
  can: peak_usb: allow flashing of the CAN channel ID
  can: peak_usb: replace unregister_netdev() with
  can: peak_usb: add ethtool interface to

Lukas Magel (3):
  can: peak_usb: export PCAN CAN channel ID as sysfs
  can: peak_usb: align CAN channel ID format in log with
  can: peak_usb: Reorder include directives

 .../ABI/testing/sysfs-class-net-peak_usb        |  19 +++
 drivers/net/can/usb/peak_usb/pcan_usb.c         |  45 +++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.c    | 122 +++++++++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h    |  12 +-
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c      |  68 +++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c     |  30 ++++-
 drivers/net/can/usb/peak_usb/pcan_usb_pro.h     |   1 +
 7 files changed, 266 insertions(+), 31 deletions(-)

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
Hi Marc,

a happy late new year! I noticed that the patch order in my first v3
submission got messed up, so I'm sending it again. I hope that with the
v3 changes the patch series now finds the approval of you and the netdev
list.

Regards,
Lukas



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

* [PATCH v3 1/8] can: peak_usb: rename device_id to CAN channel ID
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
@ 2023-01-16 20:09   ` Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 2/8] can: peak_usb: add callback to read CAN channel ID of PEAK CAN-FD devices Lukas Magel
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2023-01-16 20:09 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

The so-called "device id" is a user-defined identifier value that can be
set individually for each CAN interface of a PEAK USB device.
Contrary to a static serial number, the value can be changed by the
user. With this ID, each CAN interface can be uniquely identified even if
the USB device does not export a proper serial number or the USB device
exports multiple CAN interfaces. In order to not confuse it with the
device ID used by the USB core and emphasize the link to the CAN
interface, the functions and variables for reading this user-defined
value are renamed to CAN channel ID.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      | 10 +++++-----
 drivers/net/can/usb/peak_usb/pcan_usb_core.c |  8 ++++----
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  5 +++--
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  2 +-
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  8 ++++----
 5 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 687dd542f7f6..7b3282e5c880 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -381,19 +381,19 @@ static int pcan_usb_get_serial(struct peak_usb_device *dev, u32 *serial_number)
 }
 
 /*
- * read device id from device
+ * read can channel id from device
  */
-static int pcan_usb_get_device_id(struct peak_usb_device *dev, u32 *device_id)
+static int pcan_usb_get_can_channel_id(struct peak_usb_device *dev, u32 *can_ch_id)
 {
 	u8 args[PCAN_USB_CMD_ARGS_LEN];
 	int err;
 
 	err = pcan_usb_wait_rsp(dev, PCAN_USB_CMD_DEVID, PCAN_USB_GET, args);
 	if (err)
-		netdev_err(dev->netdev, "getting device id failure: %d\n", err);
+		netdev_err(dev->netdev, "getting can channel id failure: %d\n", err);
 
 	else
-		*device_id = args[0];
+		*can_ch_id = args[0];
 
 	return err;
 }
@@ -1017,7 +1017,7 @@ const struct peak_usb_adapter pcan_usb = {
 	.dev_init = pcan_usb_init,
 	.dev_set_bus = pcan_usb_write_mode,
 	.dev_set_bittiming = pcan_usb_set_bittiming,
-	.dev_get_device_id = pcan_usb_get_device_id,
+	.dev_get_can_channel_id = pcan_usb_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_decode_buf,
 	.dev_encode_msg = pcan_usb_encode_msg,
 	.dev_start = pcan_usb_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 225697d70a9a..a3a25a2e8d41 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -921,12 +921,12 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 			goto adap_dev_free;
 	}
 
-	/* get device number early */
-	if (dev->adapter->dev_get_device_id)
-		dev->adapter->dev_get_device_id(dev, &dev->device_number);
+	/* get CAN channel id early */
+	if (dev->adapter->dev_get_can_channel_id)
+		dev->adapter->dev_get_can_channel_id(dev, &dev->can_channel_id);
 
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
-			peak_usb_adapter->name, ctrl_idx, dev->device_number);
+			peak_usb_adapter->name, ctrl_idx, dev->can_channel_id);
 
 	return 0;
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index f6bdd8b3f290..6de0429c268f 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -60,7 +60,7 @@ struct peak_usb_adapter {
 	int (*dev_set_data_bittiming)(struct peak_usb_device *dev,
 				      struct can_bittiming *bt);
 	int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff);
-	int (*dev_get_device_id)(struct peak_usb_device *dev, u32 *device_id);
+	int (*dev_get_can_channel_id)(struct peak_usb_device *dev, u32 *can_ch_id);
 	int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb);
 	int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb,
 					u8 *obuf, size_t *size);
@@ -122,7 +122,8 @@ struct peak_usb_device {
 	u8 *cmd_buf;
 	struct usb_anchor rx_submitted;
 
-	u32 device_number;
+	/* equivalent to the device ID in the Windows API */
+	u32 can_channel_id;
 	u8 device_rev;
 
 	u8 ep_msg_in;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 2ea1500df393..2e0955900ebe 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -972,7 +972,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
 	}
 
 	pdev->usb_if->dev[dev->ctrl_idx] = dev;
-	dev->device_number =
+	dev->can_channel_id =
 		le32_to_cpu(pdev->usb_if->fw_info.dev_id[dev->ctrl_idx]);
 
 	/* if vendor rsp is of type 2, then it contains EP numbers to
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 5d8f6a40bb2c..3a13cfef47bb 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -419,8 +419,8 @@ static int pcan_usb_pro_set_led(struct peak_usb_device *dev, u8 mode,
 	return pcan_usb_pro_send_cmd(dev, &um);
 }
 
-static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
-				      u32 *device_id)
+static int pcan_usb_pro_get_can_channel_id(struct peak_usb_device *dev,
+					   u32 *can_ch_id)
 {
 	struct pcan_usb_pro_devid *pdn;
 	struct pcan_usb_pro_msg um;
@@ -439,7 +439,7 @@ static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
 		return err;
 
 	pdn = (struct pcan_usb_pro_devid *)pc;
-	*device_id = le32_to_cpu(pdn->dev_num);
+	*can_ch_id = le32_to_cpu(pdn->dev_num);
 
 	return err;
 }
@@ -1076,7 +1076,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	.dev_free = pcan_usb_pro_free,
 	.dev_set_bus = pcan_usb_pro_set_bus,
 	.dev_set_bittiming = pcan_usb_pro_set_bittiming,
-	.dev_get_device_id = pcan_usb_pro_get_device_id,
+	.dev_get_can_channel_id = pcan_usb_pro_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_pro_decode_buf,
 	.dev_encode_msg = pcan_usb_pro_encode_msg,
 	.dev_start = pcan_usb_pro_start,
-- 
2.38.1


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

* [PATCH v3 2/8] can: peak_usb: add callback to read CAN channel ID of PEAK CAN-FD devices
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 1/8] can: peak_usb: rename device_id to " Lukas Magel
@ 2023-01-16 20:09   ` Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 3/8] can: peak_usb: allow flashing of the CAN channel ID Lukas Magel
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2023-01-16 20:09 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch adds a new function that allows to read the CAN channel ID
from the non volatile memory of the USB CAN-FD PEAK devices. The CAN
channel ID is a user-configurable u8/u32 identifier value that can be set
individually for each PEAK CAN interface.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c |  3 +-
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 33 +++++++++++++++++---
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index a3a25a2e8d41..54e2481cce30 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -922,8 +922,7 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	}
 
 	/* get CAN channel id early */
-	if (dev->adapter->dev_get_can_channel_id)
-		dev->adapter->dev_get_can_channel_id(dev, &dev->can_channel_id);
+	dev->adapter->dev_get_can_channel_id(dev, &dev->can_channel_id);
 
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
 			peak_usb_adapter->name, ctrl_idx, dev->can_channel_id);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 2e0955900ebe..a70ef0c7a800 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -234,6 +234,15 @@ static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
 	return err;
 }
 
+static int pcan_usb_fd_read_fwinfo(struct peak_usb_device *dev,
+				   struct pcan_ufd_fw_info *fw_info)
+{
+	return pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
+				     PCAN_USBPRO_INFO_FW,
+				     fw_info,
+				     sizeof(*fw_info));
+}
+
 /* build the commands list in the given buffer, to enter operational mode */
 static int pcan_usb_fd_build_restart_cmd(struct peak_usb_device *dev, u8 *buf)
 {
@@ -434,6 +443,21 @@ static int pcan_usb_fd_set_bittiming_fast(struct peak_usb_device *dev,
 	return pcan_usb_fd_send_cmd(dev, ++cmd);
 }
 
+/* read user CAN channel id from device */
+static int pcan_usb_fd_get_can_channel_id(struct peak_usb_device *dev,
+					  u32 *can_ch_id)
+{
+	int err;
+	struct pcan_usb_fd_if *usb_if = pcan_usb_fd_dev_if(dev);
+
+	err = pcan_usb_fd_read_fwinfo(dev, &usb_if->fw_info);
+	if (err)
+		return err;
+
+	*can_ch_id = le32_to_cpu(usb_if->fw_info.dev_id[dev->ctrl_idx]);
+	return err;
+}
+
 /* handle restart but in asynchronously way
  * (uses PCAN-USB Pro code to complete asynchronous request)
  */
@@ -907,10 +931,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
 
 		fw_info = &pdev->usb_if->fw_info;
 
-		err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
-					    PCAN_USBPRO_INFO_FW,
-					    fw_info,
-					    sizeof(*fw_info));
+		err = pcan_usb_fd_read_fwinfo(dev, fw_info);
 		if (err) {
 			dev_err(dev->netdev->dev.parent,
 				"unable to read %s firmware info (err %d)\n",
@@ -1148,6 +1169,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1222,6 +1244,7 @@ const struct peak_usb_adapter pcan_usb_chip = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1296,6 +1319,7 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1370,6 +1394,7 @@ const struct peak_usb_adapter pcan_usb_x6 = {
 	.dev_set_bus = pcan_usb_fd_set_bus,
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
-- 
2.38.1


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

* [PATCH v3 3/8] can: peak_usb: allow flashing of the CAN channel ID
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 1/8] can: peak_usb: rename device_id to " Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 2/8] can: peak_usb: add callback to read CAN channel ID of PEAK CAN-FD devices Lukas Magel
@ 2023-01-16 20:09   ` Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 4/8] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2023-01-16 20:09 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch adds callbacks that allow the user to set a new self-defined
CAN channel ID to all USB - CAN/CANFD interfaces of PEAK-System managed by
this driver, namely:
- PCAN-USB
- PCAN-USB FD
- PCAN-USB Pro FD
- PCAN-USB X6
- PCAN-Chip USB
- PCAN-USB Pro

The callback functions write the CAN channel ID to the non-volatile
memory of the devices.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      | 26 ++++++++++++++++++--
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  1 +
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   | 26 ++++++++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  | 15 +++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_pro.h  |  1 +
 5 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 7b3282e5c880..92472149cfba 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -9,10 +9,12 @@
  * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
  */
 #include <asm/unaligned.h>
+
+#include <linux/ethtool.h>
+#include <linux/limits.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -398,6 +400,25 @@ static int pcan_usb_get_can_channel_id(struct peak_usb_device *dev, u32 *can_ch_
 	return err;
 }
 
+/* set a new CAN channel id in the flash memory of the device */
+static int pcan_usb_set_can_channel_id(struct peak_usb_device *dev, u32 can_ch_id)
+{
+	u8 args[PCAN_USB_CMD_ARGS_LEN];
+
+	/* this kind of device supports 8-bit values only */
+	if (can_ch_id > U8_MAX)
+		return -EINVAL;
+
+	/* during the flash process the device disconnects during ~1.25 s.:
+	 * prohibit access when interface is UP
+	 */
+	if (dev->netdev->flags & IFF_UP)
+		return -EBUSY;
+
+	args[0] = can_ch_id;
+	return pcan_usb_send_cmd(dev, PCAN_USB_CMD_DEVID, PCAN_USB_SET, args);
+}
+
 /*
  * update current time ref with received timestamp
  */
@@ -1018,6 +1039,7 @@ const struct peak_usb_adapter pcan_usb = {
 	.dev_set_bus = pcan_usb_write_mode,
 	.dev_set_bittiming = pcan_usb_set_bittiming,
 	.dev_get_can_channel_id = pcan_usb_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_decode_buf,
 	.dev_encode_msg = pcan_usb_encode_msg,
 	.dev_start = pcan_usb_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 6de0429c268f..1e461aef0f2a 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -61,6 +61,7 @@ struct peak_usb_adapter {
 				      struct can_bittiming *bt);
 	int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff);
 	int (*dev_get_can_channel_id)(struct peak_usb_device *dev, u32 *can_ch_id);
+	int (*dev_set_can_channel_id)(struct peak_usb_device *dev, u32 can_ch_id);
 	int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb);
 	int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb,
 					u8 *obuf, size_t *size);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index a70ef0c7a800..1ea4cfdfd640 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -147,6 +147,15 @@ struct __packed pcan_ufd_ovr_msg {
 	u8	unused[3];
 };
 
+#define PCAN_UFD_CMD_DEVID_SET		0x81
+
+struct __packed pcan_ufd_device_id {
+	__le16	opcode_channel;
+
+	u16	unused;
+	__le32	device_id;
+};
+
 static inline int pufd_omsg_get_channel(struct pcan_ufd_ovr_msg *om)
 {
 	return om->channel & 0xf;
@@ -458,6 +467,19 @@ static int pcan_usb_fd_get_can_channel_id(struct peak_usb_device *dev,
 	return err;
 }
 
+/* set a new CAN channel id in the flash memory of the device */
+static int pcan_usb_fd_set_can_channel_id(struct peak_usb_device *dev, u32 can_ch_id)
+{
+	struct pcan_ufd_device_id *cmd = pcan_usb_fd_cmd_buffer(dev);
+
+	cmd->opcode_channel = pucan_cmd_opcode_channel(dev->ctrl_idx,
+						       PCAN_UFD_CMD_DEVID_SET);
+	cmd->device_id = cpu_to_le32(can_ch_id);
+
+	/* send the command */
+	return pcan_usb_fd_send_cmd(dev, ++cmd);
+}
+
 /* handle restart but in asynchronously way
  * (uses PCAN-USB Pro code to complete asynchronous request)
  */
@@ -1170,6 +1192,7 @@ const struct peak_usb_adapter pcan_usb_fd = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_fd_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1245,6 +1268,7 @@ const struct peak_usb_adapter pcan_usb_chip = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_fd_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1320,6 +1344,7 @@ const struct peak_usb_adapter pcan_usb_pro_fd = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_fd_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
@@ -1395,6 +1420,7 @@ const struct peak_usb_adapter pcan_usb_x6 = {
 	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
 	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
 	.dev_get_can_channel_id = pcan_usb_fd_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_fd_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_fd_decode_buf,
 	.dev_start = pcan_usb_fd_start,
 	.dev_stop = pcan_usb_fd_stop,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 3a13cfef47bb..061f04c20f96 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -76,6 +76,7 @@ static u16 pcan_usb_pro_sizeof_rec[256] = {
 	[PCAN_USBPRO_SETFILTR] = sizeof(struct pcan_usb_pro_filter),
 	[PCAN_USBPRO_SETTS] = sizeof(struct pcan_usb_pro_setts),
 	[PCAN_USBPRO_GETDEVID] = sizeof(struct pcan_usb_pro_devid),
+	[PCAN_USBPRO_SETDEVID] = sizeof(struct pcan_usb_pro_devid),
 	[PCAN_USBPRO_SETLED] = sizeof(struct pcan_usb_pro_setled),
 	[PCAN_USBPRO_RXMSG8] = sizeof(struct pcan_usb_pro_rxmsg),
 	[PCAN_USBPRO_RXMSG4] = sizeof(struct pcan_usb_pro_rxmsg) - 4,
@@ -149,6 +150,7 @@ static int pcan_msg_add_rec(struct pcan_usb_pro_msg *pm, int id, ...)
 
 	case PCAN_USBPRO_SETBTR:
 	case PCAN_USBPRO_GETDEVID:
+	case PCAN_USBPRO_SETDEVID:
 		*pc++ = va_arg(ap, int);
 		pc += 2;
 		*(__le32 *)pc = cpu_to_le32(va_arg(ap, u32));
@@ -444,6 +446,18 @@ static int pcan_usb_pro_get_can_channel_id(struct peak_usb_device *dev,
 	return err;
 }
 
+static int pcan_usb_pro_set_can_channel_id(struct peak_usb_device *dev,
+					   u32 can_ch_id)
+{
+	struct pcan_usb_pro_msg um;
+
+	pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+	pcan_msg_add_rec(&um, PCAN_USBPRO_SETDEVID, dev->ctrl_idx,
+			 can_ch_id);
+
+	return pcan_usb_pro_send_cmd(dev, &um);
+}
+
 static int pcan_usb_pro_set_bittiming(struct peak_usb_device *dev,
 				      struct can_bittiming *bt)
 {
@@ -1077,6 +1091,7 @@ const struct peak_usb_adapter pcan_usb_pro = {
 	.dev_set_bus = pcan_usb_pro_set_bus,
 	.dev_set_bittiming = pcan_usb_pro_set_bittiming,
 	.dev_get_can_channel_id = pcan_usb_pro_get_can_channel_id,
+	.dev_set_can_channel_id = pcan_usb_pro_set_can_channel_id,
 	.dev_decode_buf = pcan_usb_pro_decode_buf,
 	.dev_encode_msg = pcan_usb_pro_encode_msg,
 	.dev_start = pcan_usb_pro_start,
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
index a34e0fc021c9..28e740af905d 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
@@ -62,6 +62,7 @@ struct __packed pcan_usb_pro_fwinfo {
 #define PCAN_USBPRO_SETBTR	0x02
 #define PCAN_USBPRO_SETBUSACT	0x04
 #define PCAN_USBPRO_SETSILENT	0x05
+#define PCAN_USBPRO_SETDEVID	0x06
 #define PCAN_USBPRO_SETFILTR	0x0a
 #define PCAN_USBPRO_SETTS	0x10
 #define PCAN_USBPRO_GETDEVID	0x12
-- 
2.38.1


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

* [PATCH v3 4/8] can: peak_usb: replace unregister_netdev() with unregister_candev()
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
                     ` (2 preceding siblings ...)
  2023-01-16 20:09   ` [PATCH v3 3/8] can: peak_usb: allow flashing of the CAN channel ID Lukas Magel
@ 2023-01-16 20:09   ` Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 5/8] can: peak_usb: add ethtool interface to user-configurable CAN channel identifier Lukas Magel
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2023-01-16 20:09 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch changes the call to unregister_netdev() in
peak_usb_disconnect() with unregister_candev().

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 54e2481cce30..4eff4b4706b9 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -963,7 +963,7 @@ static void peak_usb_disconnect(struct usb_interface *intf)
 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
 		strscpy(name, netdev->name, IFNAMSIZ);
 
-		unregister_netdev(netdev);
+		unregister_candev(netdev);
 
 		kfree(dev->cmd_buf);
 		dev->next_siblings = NULL;
-- 
2.38.1


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

* [PATCH v3 5/8] can: peak_usb: add ethtool interface to user-configurable CAN channel identifier
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
                     ` (3 preceding siblings ...)
  2023-01-16 20:09   ` [PATCH v3 4/8] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
@ 2023-01-16 20:09   ` Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 6/8] can: peak_usb: export PCAN CAN channel ID as sysfs device attribute Lukas Magel
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2023-01-16 20:09 UTC (permalink / raw)
  To: linux-can; +Cc: Stephane Grosjean, Lukas Magel

From: Stephane Grosjean <s.grosjean@peak-system.com>

This patch introduces 3 new functions implementing support for ethtool
access to the CAN channel ID of all USB CAN network interfaces managed by
the driver. With this patch, it is possible to read/write the CAN
channel ID from/to the EEPROM via the ethtool interface.

The CAN channel ID is a user-configurable device identifier that can be
set individually for each CAN interface of a PEAK USB device. Depending on
the device, the identifier has a length of 8 or 32 bit. The identifier
is stored in the non-volatile memory of the device.

The identifier of a CAN interface can be read/written as an 8 or 32 bit
byte string in native (little-endian) byte order, where the length depends
on the device type.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb.c      |  9 +++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 80 ++++++++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.h |  6 ++
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  3 +
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  3 +
 5 files changed, 101 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 92472149cfba..5a712a2beb5a 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -984,9 +984,18 @@ static int pcan_usb_set_phys_id(struct net_device *netdev,
 	return err;
 }
 
+/* This device only handles 8-bit CAN channel id. */
+static int pcan_usb_get_eeprom_len(struct net_device *netdev)
+{
+	return sizeof(u8);
+}
+
 static const struct ethtool_ops pcan_usb_ethtool_ops = {
 	.set_phys_id = pcan_usb_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= pcan_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /*
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 4eff4b4706b9..d5ebcee7b7ed 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -808,6 +808,86 @@ static const struct net_device_ops peak_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+/* CAN-USB devices generally handle 32-bit CAN channel IDs.
+ * In case one doesn't, then it have to overload this function.
+ */
+int peak_usb_get_eeprom_len(struct net_device *netdev)
+{
+	return sizeof(u32);
+}
+
+/* Every CAN-USB device exports the dev_get_can_channel_id() operation. It is used
+ * here to fill the data buffer with the user defined CAN channel ID.
+ */
+int peak_usb_get_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct peak_usb_device *dev = netdev_priv(netdev);
+	u32 ch_id;
+	__le32 ch_id_le;
+	int err;
+
+	err = dev->adapter->dev_get_can_channel_id(dev, &ch_id);
+	if (err)
+		return err;
+
+	/* ethtool operates on individual bytes. The byte order of the CAN
+	 * channel id in memory depends on the kernel architecture. We
+	 * convert the CAN channel id back to the native byte order of the PEAK
+	 * device itself to ensure that the order is consistent for all
+	 * host architectures.
+	 */
+	ch_id_le = cpu_to_le32(ch_id);
+	memcpy(data, (u8 *)&ch_id_le + eeprom->offset, eeprom->len);
+
+	/* update cached value */
+	dev->can_channel_id = ch_id;
+	return err;
+}
+
+/* Every CAN-USB device exports the dev_get_can_channel_id()/dev_set_can_channel_id()
+ * operations. They are used here to set the new user defined CAN channel ID.
+ */
+int peak_usb_set_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data)
+{
+	struct peak_usb_device *dev = netdev_priv(netdev);
+	u32 ch_id;
+	__le32 ch_id_le;
+	int err;
+
+	/* first, read the current user defined CAN channel ID */
+	err = dev->adapter->dev_get_can_channel_id(dev, &ch_id);
+	if (err) {
+		netdev_err(netdev, "Failed to init CAN channel id (err %d)\n", err);
+		return err;
+	}
+
+	/* do update the value with user given bytes.
+	 * ethtool operates on individual bytes. The byte order of the CAN
+	 * channel ID in memory depends on the kernel architecture. We
+	 * convert the CAN channel ID back to the native byte order of the PEAK
+	 * device itself to ensure that the order is consistent for all
+	 * host architectures.
+	 */
+	ch_id_le = cpu_to_le32(ch_id);
+	memcpy((u8 *)&ch_id_le + eeprom->offset, data, eeprom->len);
+	ch_id = le32_to_cpu(ch_id_le);
+
+	/* flash the new value now */
+	err = dev->adapter->dev_set_can_channel_id(dev, ch_id);
+	if (err) {
+		netdev_err(netdev, "Failed to write new CAN channel id (err %d)\n",
+			   err);
+		return err;
+	}
+
+	/* update cached value with the new one */
+	dev->can_channel_id = ch_id;
+
+	return 0;
+}
+
 int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
 {
 	info->so_timestamping =
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 1e461aef0f2a..980e315186cf 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -149,4 +149,10 @@ void peak_usb_async_complete(struct urb *urb);
 void peak_usb_restart_complete(struct peak_usb_device *dev);
 int pcan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
 
+/* common 32-bit CAN channel ID ethtool management */
+int peak_usb_get_eeprom_len(struct net_device *netdev);
+int peak_usb_get_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data);
+int peak_usb_set_eeprom(struct net_device *netdev,
+			struct ethtool_eeprom *eeprom, u8 *data);
 #endif
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 1ea4cfdfd640..fd925ae96331 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1124,6 +1124,9 @@ static int pcan_usb_fd_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_fd_ethtool_ops = {
 	.set_phys_id = pcan_usb_fd_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= peak_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /* describes the PCAN-USB FD adapter */
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 061f04c20f96..0c805d9672bf 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -1037,6 +1037,9 @@ static int pcan_usb_pro_set_phys_id(struct net_device *netdev,
 static const struct ethtool_ops pcan_usb_pro_ethtool_ops = {
 	.set_phys_id = pcan_usb_pro_set_phys_id,
 	.get_ts_info = pcan_get_ts_info,
+	.get_eeprom_len	= peak_usb_get_eeprom_len,
+	.get_eeprom = peak_usb_get_eeprom,
+	.set_eeprom = peak_usb_set_eeprom,
 };
 
 /*
-- 
2.38.1


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

* [PATCH v3 6/8] can: peak_usb: export PCAN CAN channel ID as sysfs device attribute
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
                     ` (4 preceding siblings ...)
  2023-01-16 20:09   ` [PATCH v3 5/8] can: peak_usb: add ethtool interface to user-configurable CAN channel identifier Lukas Magel
@ 2023-01-16 20:09   ` Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 7/8] can: peak_usb: align CAN channel ID format in log with sysfs attribute Lukas Magel
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2023-01-16 20:09 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel, Stephane Grosjean

This patch exports the CAN channel ID as a sysfs attribute. The CAN
channel ID is a user-configurable u8/u32 identifier that can be set
individually for each CAN interface of a PEAK USB device.

Exporting the channel ID as a sysfs attribute allows users to easily read
the ID and to write udev rules that can match against the ID. This is
especially useful for PEAK USB devices that do not export a serial
number at SUB level.

Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 .../ABI/testing/sysfs-class-net-peak_usb      | 19 ++++++++++++++
 drivers/net/can/usb/peak_usb/pcan_usb_core.c  | 25 +++++++++++++++++++
 2 files changed, 44 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-net-peak_usb

diff --git a/Documentation/ABI/testing/sysfs-class-net-peak_usb b/Documentation/ABI/testing/sysfs-class-net-peak_usb
new file mode 100644
index 000000000000..9e3d0bf4d4b2
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-net-peak_usb
@@ -0,0 +1,19 @@
+
+What:		/sys/class/net/<iface>/peak_usb/can_channel_id
+Date:		November 2022
+KernelVersion:	6.2
+Contact:	Stephane Grosjean <s.grosjean@peak-system.com>
+Description:
+		PEAK PCAN-USB devices support user-configurable CAN channel
+		identifiers. Contrary to a USB serial number, these identifiers
+		are writable and can be set per CAN interface. This means that
+		if a USB device exports multiple CAN interfaces, each of them
+		can be assigned a unique channel ID.
+		This attribute provides read-only access to the currently
+		configured value of the channel identifier. Depending on the
+		device type, the identifier has a length of 8 or 32 bit. The
+		value read from this attribute is always an 8 digit 32 bit
+		hexadecimal value in big endian format. If the device only
+		supports an 8 bit identifier, the upper 24 bit of the value are
+		set to zero.
+
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index d5ebcee7b7ed..89ad5fda19c6 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -15,6 +15,8 @@
 #include <linux/netdevice.h>
 #include <linux/usb.h>
 #include <linux/ethtool.h>
+#include <linux/sysfs.h>
+#include <linux/device.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -53,6 +55,26 @@ static const struct usb_device_id peak_usb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, peak_usb_table);
 
+static ssize_t can_channel_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct net_device *netdev = to_net_dev(dev);
+	struct peak_usb_device *peak_dev = netdev_priv(netdev);
+
+	return sysfs_emit(buf, "%08X\n", peak_dev->can_channel_id);
+}
+static DEVICE_ATTR_RO(can_channel_id);
+
+/* mutable to avoid cast in attribute_group */
+static struct attribute *peak_usb_sysfs_attrs[] = {
+	&dev_attr_can_channel_id.attr,
+	NULL,
+};
+
+static const struct attribute_group peak_usb_sysfs_group = {
+	.name	= "peak_usb",
+	.attrs	= peak_usb_sysfs_attrs,
+};
+
 /*
  * dump memory
  */
@@ -961,6 +983,9 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	/* add ethtool support */
 	netdev->ethtool_ops = peak_usb_adapter->ethtool_ops;
 
+	/* register peak_usb sysfs files */
+	netdev->sysfs_groups[0] = &peak_usb_sysfs_group;
+
 	init_usb_anchor(&dev->rx_submitted);
 
 	init_usb_anchor(&dev->tx_submitted);
-- 
2.38.1


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

* [PATCH v3 7/8] can: peak_usb: align CAN channel ID format in log with sysfs attribute
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
                     ` (5 preceding siblings ...)
  2023-01-16 20:09   ` [PATCH v3 6/8] can: peak_usb: export PCAN CAN channel ID as sysfs device attribute Lukas Magel
@ 2023-01-16 20:09   ` Lukas Magel
  2023-01-16 20:09   ` [PATCH v3 8/8] can: peak_usb: Reorder include directives alphabetically Lukas Magel
  2023-02-02 16:45   ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Marc Kleine-Budde
  8 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2023-01-16 20:09 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel

Previously, the CAN channel ID was printed to the kernel log in decimal
upon connecting a new PEAK device. This behavior is inconsistent with
the hexadecimal format of the CAN channel ID sysfs attribute. This patch
updates the log message to output the id in hexadecimal.

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 89ad5fda19c6..926d1359f433 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -1029,8 +1029,8 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	/* get CAN channel id early */
 	dev->adapter->dev_get_can_channel_id(dev, &dev->can_channel_id);
 
-	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
-			peak_usb_adapter->name, ctrl_idx, dev->can_channel_id);
+	netdev_info(netdev, "attached to %s channel %u (device 0x%08X)\n",
+		    peak_usb_adapter->name, ctrl_idx, dev->can_channel_id);
 
 	return 0;
 
-- 
2.38.1


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

* [PATCH v3 8/8] can: peak_usb: Reorder include directives alphabetically
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
                     ` (6 preceding siblings ...)
  2023-01-16 20:09   ` [PATCH v3 7/8] can: peak_usb: align CAN channel ID format in log with sysfs attribute Lukas Magel
@ 2023-01-16 20:09   ` Lukas Magel
  2023-02-02 16:45   ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Marc Kleine-Budde
  8 siblings, 0 replies; 48+ messages in thread
From: Lukas Magel @ 2023-01-16 20:09 UTC (permalink / raw)
  To: linux-can; +Cc: Lukas Magel

The include directives in all source files are reordered alphabetically
according to the names of the header files.

Signed-off-by: Lukas Magel <lukas.magel@posteo.net>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 10 +++++-----
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  4 ++--
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c  |  4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 926d1359f433..f7305edc2784 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -8,15 +8,15 @@
  *
  * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
  */
+#include <linux/device.h>
+#include <linux/ethtool.h>
 #include <linux/init.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
-#include <linux/usb.h>
-#include <linux/ethtool.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/device.h>
+#include <linux/usb.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index fd925ae96331..4d85b29a17b7 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -4,10 +4,10 @@
  *
  * Copyright (C) 2013-2014 Stephane Grosjean <s.grosjean@peak-system.com>
  */
+#include <linux/ethtool.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 0c805d9672bf..f736196383ac 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -6,10 +6,10 @@
  * Copyright (C) 2003-2011 PEAK System-Technik GmbH
  * Copyright (C) 2011-2012 Stephane Grosjean <s.grosjean@peak-system.com>
  */
+#include <linux/ethtool.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/usb.h>
-#include <linux/module.h>
-#include <linux/ethtool.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
-- 
2.38.1


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

* Re: [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID
  2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
                     ` (7 preceding siblings ...)
  2023-01-16 20:09   ` [PATCH v3 8/8] can: peak_usb: Reorder include directives alphabetically Lukas Magel
@ 2023-02-02 16:45   ` Marc Kleine-Budde
  8 siblings, 0 replies; 48+ messages in thread
From: Marc Kleine-Budde @ 2023-02-02 16:45 UTC (permalink / raw)
  To: Lukas Magel; +Cc: linux-can, Stephane Grosjean

[-- Attachment #1: Type: text/plain, Size: 1449 bytes --]

On 16.01.2023 20:09:24, Lukas Magel wrote:
> This series of patches introduces the CAN channel ID for the PEAK USB
> CAN interfaces. The id can be read/written via ethtool and is exposed as
> a read-only attribute via sysfs. This allows users to set the id via
> ethtool and write udev rules to match against the sysfs attribute.
> 
> Part of the patches were originally introduced by Stéphane Grosjean and
> were modified. See the following threads for the original patches:
> 
> * https://lore.kernel.org/linux-can/20220128150157.1222850-1-s.grosjean@peak-system.com/T/#mad8014c9f1c89a50d5944a50ae0a585edec79eab
> * https://lore.kernel.org/linux-can/20211117150132.37056-1-s.grosjean@peak-system.com/T/#mbf1d7db8433734a1fe08868d79f9927a04fe7ffe

[...]

> Hi Marc,
> 
> a happy late new year!

Even later happy new year! :)

> I noticed that the patch order in my first v3
> submission got messed up, so I'm sending it again. I hope that with the
> v3 changes the patch series now finds the approval of you and the netdev
> list.

Applied to linux-can-next. It will be included in my next pull request,
let's see what the netdev people say.

Marc

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

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

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

end of thread, other threads:[~2023-02-02 16:45 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-01  8:04 [PATCH v1] can: peak_usb: export PCAN device ID as sysfs device attribute Lukas Magel
2022-08-01 14:36 ` Vincent MAILHOL
2022-08-02 19:26   ` [PATCH v2] " Lukas Magel
2022-09-15  9:54 ` [RESEND PATCH " Lukas Magel
2022-09-28 20:43   ` Lukas Magel
2022-09-30 12:06     ` Marc Kleine-Budde
2022-09-30 14:20       ` Marc Kleine-Budde
2022-10-22 21:57         ` Lukas Magel
2022-10-22 21:35 ` [PATCH 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
2022-10-22 21:35   ` [PATCH 1/7] can: peak_usb: rename device_id to a more explicit name Lukas Magel
2022-10-22 21:35   ` [PATCH 2/7] can: peak_usb: add callback to read user value of CANFD devices Lukas Magel
2022-10-22 21:35   ` [PATCH 3/7] can: peak_usb: allow flashing of the user device id Lukas Magel
2022-10-22 21:35   ` [PATCH 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
2022-10-25 13:30     ` Marc Kleine-Budde
2022-10-22 21:35   ` [PATCH 5/7] can: peak_usb: add ethtool interface to user defined flashed device number Lukas Magel
2022-10-25 14:54     ` Marc Kleine-Budde
2022-10-22 21:35   ` [PATCH 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute Lukas Magel
2022-10-25 13:30     ` Marc Kleine-Budde
2022-10-22 21:35   ` [PATCH 7/7] can: peak_usb: align user device id format in log with sysfs attribute Lukas Magel
2022-10-25 11:28     ` Marc Kleine-Budde
2022-10-25 11:44       ` Marc Kleine-Budde
2022-10-30 10:59 ` [PATCH v2 0/7] can: peak_usb: Introduce configurable user dev id Lukas Magel
2022-10-30 10:59   ` [PATCH v2 1/7] can: peak_usb: rename device_id to a more explicit name Lukas Magel
2022-10-30 10:59   ` [PATCH v2 2/7] can: peak_usb: add callback to read user value of CANFD devices Lukas Magel
2022-10-30 10:59   ` [PATCH v2 3/7] can: peak_usb: allow flashing of the user device id Lukas Magel
2022-10-30 10:59   ` [PATCH v2 4/7] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
2022-10-30 10:59   ` [PATCH v2 5/7] can: peak_usb: add ethtool interface to user defined flashed device number Lukas Magel
2022-10-30 10:59   ` [PATCH v2 6/7] can: peak_usb: export PCAN user device ID as sysfs device attribute Lukas Magel
2022-10-30 10:59   ` [PATCH v2 7/7] can: peak_usb: align user device id format in log with sysfs attribute Lukas Magel
2022-12-13  8:03 ` [PATCH v3 0/7] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
2022-12-13  8:03 ` [PATCH v3 1/8] can: peak_usb: rename device_id to " Lukas Magel
2022-12-13  8:03 ` [PATCH v3 2/8] can: peak_usb: add callback to read CAN channel ID of PEAK CAN-FD devices Lukas Magel
2022-12-13  8:03 ` [PATCH v3 3/8] can: peak_usb: allow flashing of the CAN channel ID Lukas Magel
2022-12-13  8:03 ` [PATCH v3 4/8] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
2022-12-13  8:03 ` [PATCH v3 5/8] can: peak_usb: add ethtool interface to user-configurable CAN channel identifier Lukas Magel
2022-12-13  8:03 ` [PATCH v3 6/8] can: peak_usb: export PCAN CAN channel ID as sysfs device attribute Lukas Magel
2022-12-13  8:03 ` [PATCH v3 7/8] can: peak_usb: align CAN channel ID format in log with sysfs attribute Lukas Magel
2022-12-13  8:03 ` [PATCH v3 8/8] can: peak_usb: Reorder include directives alphabetically Lukas Magel
2023-01-16 20:09 ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Lukas Magel
2023-01-16 20:09   ` [PATCH v3 1/8] can: peak_usb: rename device_id to " Lukas Magel
2023-01-16 20:09   ` [PATCH v3 2/8] can: peak_usb: add callback to read CAN channel ID of PEAK CAN-FD devices Lukas Magel
2023-01-16 20:09   ` [PATCH v3 3/8] can: peak_usb: allow flashing of the CAN channel ID Lukas Magel
2023-01-16 20:09   ` [PATCH v3 4/8] can: peak_usb: replace unregister_netdev() with unregister_candev() Lukas Magel
2023-01-16 20:09   ` [PATCH v3 5/8] can: peak_usb: add ethtool interface to user-configurable CAN channel identifier Lukas Magel
2023-01-16 20:09   ` [PATCH v3 6/8] can: peak_usb: export PCAN CAN channel ID as sysfs device attribute Lukas Magel
2023-01-16 20:09   ` [PATCH v3 7/8] can: peak_usb: align CAN channel ID format in log with sysfs attribute Lukas Magel
2023-01-16 20:09   ` [PATCH v3 8/8] can: peak_usb: Reorder include directives alphabetically Lukas Magel
2023-02-02 16:45   ` [RESEND PATCH v3 0/8] can: peak_usb: Introduce configurable CAN channel ID Marc Kleine-Budde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).