can: etas_es58x: add devlink port support
authorVincent Mailhol <mailhol.vincent@wanadoo.fr>
Wed, 30 Nov 2022 17:46:53 +0000 (02:46 +0900)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Mon, 12 Dec 2022 10:39:12 +0000 (11:39 +0100)
Add support for devlink port which extends the devlink support to the
network interface level. For now, the etas_es58x driver will only rely
on the default features that devlink port has to offer and not
implement additional feature ones.

Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/all/20221130174658.29282-3-mailhol.vincent@wanadoo.fr
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/usb/etas_es58x/es58x_core.c
drivers/net/can/usb/etas_es58x/es58x_core.h

index aeffe61..de884de 100644 (file)
@@ -2039,10 +2039,16 @@ static int es58x_set_mode(struct net_device *netdev, enum can_mode mode)
  * @es58x_dev: ES58X device.
  * @priv: ES58X private parameters related to the network device.
  * @channel_idx: Index of the network device.
+ *
+ * Return: zero on success, errno if devlink port could not be
+ *     properly registered.
  */
-static void es58x_init_priv(struct es58x_device *es58x_dev,
-                           struct es58x_priv *priv, int channel_idx)
+static int es58x_init_priv(struct es58x_device *es58x_dev,
+                          struct es58x_priv *priv, int channel_idx)
 {
+       struct devlink_port_attrs attrs = {
+               .flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL,
+       };
        const struct es58x_parameters *param = es58x_dev->param;
        struct can_priv *can = &priv->can;
 
@@ -2061,6 +2067,10 @@ static void es58x_init_priv(struct es58x_device *es58x_dev,
        can->state = CAN_STATE_STOPPED;
        can->ctrlmode_supported = param->ctrlmode_supported;
        can->do_set_mode = es58x_set_mode;
+
+       devlink_port_attrs_set(&priv->devlink_port, &attrs);
+       return devlink_port_register(priv_to_devlink(es58x_dev),
+                                    &priv->devlink_port, channel_idx);
 }
 
 /**
@@ -2084,7 +2094,10 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
        }
        SET_NETDEV_DEV(netdev, dev);
        es58x_dev->netdev[channel_idx] = netdev;
-       es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx);
+       ret = es58x_init_priv(es58x_dev, es58x_priv(netdev), channel_idx);
+       if (ret)
+               goto free_candev;
+       SET_NETDEV_DEVLINK_PORT(netdev, &es58x_priv(netdev)->devlink_port);
 
        netdev->netdev_ops = &es58x_netdev_ops;
        netdev->ethtool_ops = &es58x_ethtool_ops;
@@ -2092,16 +2105,20 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx)
        netdev->dev_port = channel_idx;
 
        ret = register_candev(netdev);
-       if (ret) {
-               es58x_dev->netdev[channel_idx] = NULL;
-               free_candev(netdev);
-               return ret;
-       }
+       if (ret)
+               goto devlink_port_unregister;
 
        netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0),
                                       es58x_dev->param->dql_min_limit);
 
        return ret;
+
+ devlink_port_unregister:
+       devlink_port_unregister(&es58x_priv(netdev)->devlink_port);
+ free_candev:
+       es58x_dev->netdev[channel_idx] = NULL;
+       free_candev(netdev);
+       return ret;
 }
 
 /**
@@ -2118,6 +2135,7 @@ static void es58x_free_netdevs(struct es58x_device *es58x_dev)
                if (!netdev)
                        continue;
                unregister_candev(netdev);
+               devlink_port_unregister(&es58x_priv(netdev)->devlink_port);
                es58x_dev->netdev[i] = NULL;
                free_candev(netdev);
        }
index bf24375..a767891 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/netdevice.h>
 #include <linux/types.h>
 #include <linux/usb.h>
+#include <net/devlink.h>
 
 #include "es581_4.h"
 #include "es58x_fd.h"
@@ -230,6 +231,7 @@ union es58x_urb_cmd {
  * @can: struct can_priv must be the first member (Socket CAN relies
  *     on the fact that function netdev_priv() returns a pointer to
  *     a struct can_priv).
+ * @devlink_port: devlink instance for the network interface.
  * @es58x_dev: pointer to the corresponding ES58X device.
  * @tx_urb: Used as a buffer to concatenate the TX messages and to do
  *     a bulk send. Please refer to es58x_start_xmit() for more
@@ -255,6 +257,7 @@ union es58x_urb_cmd {
  */
 struct es58x_priv {
        struct can_priv can;
+       struct devlink_port devlink_port;
        struct es58x_device *es58x_dev;
        struct urb *tx_urb;