Commit 09d4d087 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

mlx4: Implement devlink interface

Implement newly introduced devlink interface. Add devlink port instances
for every port and set the port types accordingly.
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
v2->v3:
-add dev param to devlink_register (api change)
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bfcd3a46
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <net/ipv6.h> #include <net/ipv6.h>
#include <net/addrconf.h> #include <net/addrconf.h>
#include <net/devlink.h>
#include <rdma/ib_smi.h> #include <rdma/ib_smi.h>
#include <rdma/ib_user_verbs.h> #include <rdma/ib_user_verbs.h>
...@@ -2519,6 +2520,9 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) ...@@ -2519,6 +2520,9 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
} }
ibdev->ib_active = true; ibdev->ib_active = true;
mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
devlink_port_type_ib_set(mlx4_get_devlink_port(dev, i),
&ibdev->ib_dev);
if (mlx4_is_mfunc(ibdev->dev)) if (mlx4_is_mfunc(ibdev->dev))
init_pkeys(ibdev); init_pkeys(ibdev);
...@@ -2643,7 +2647,10 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr) ...@@ -2643,7 +2647,10 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
{ {
struct mlx4_ib_dev *ibdev = ibdev_ptr; struct mlx4_ib_dev *ibdev = ibdev_ptr;
int p; int p;
int i;
mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
devlink_port_type_clear(mlx4_get_devlink_port(dev, i));
ibdev->ib_active = false; ibdev->ib_active = false;
flush_workqueue(wq); flush_workqueue(wq);
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <net/ip.h> #include <net/ip.h>
#include <net/busy_poll.h> #include <net/busy_poll.h>
#include <net/vxlan.h> #include <net/vxlan.h>
#include <net/devlink.h>
#include <linux/mlx4/driver.h> #include <linux/mlx4/driver.h>
#include <linux/mlx4/device.h> #include <linux/mlx4/device.h>
...@@ -2033,8 +2034,11 @@ void mlx4_en_destroy_netdev(struct net_device *dev) ...@@ -2033,8 +2034,11 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port); en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
/* Unregister device - this will close the port if it was up */ /* Unregister device - this will close the port if it was up */
if (priv->registered) if (priv->registered) {
devlink_port_type_clear(mlx4_get_devlink_port(mdev->dev,
priv->port));
unregister_netdev(dev); unregister_netdev(dev);
}
if (priv->allocated) if (priv->allocated)
mlx4_free_hwq_res(mdev->dev, &priv->res, MLX4_EN_PAGE_SIZE); mlx4_free_hwq_res(mdev->dev, &priv->res, MLX4_EN_PAGE_SIZE);
...@@ -3051,6 +3055,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, ...@@ -3051,6 +3055,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
} }
priv->registered = 1; priv->registered = 1;
devlink_port_type_eth_set(mlx4_get_devlink_port(mdev->dev, priv->port),
dev);
return 0; return 0;
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <net/devlink.h>
#include "mlx4.h" #include "mlx4.h"
...@@ -249,3 +250,11 @@ void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int ...@@ -249,3 +250,11 @@ void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int
return result; return result;
} }
EXPORT_SYMBOL_GPL(mlx4_get_protocol_dev); EXPORT_SYMBOL_GPL(mlx4_get_protocol_dev);
struct devlink_port *mlx4_get_devlink_port(struct mlx4_dev *dev, int port)
{
struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
return &info->devlink_port;
}
EXPORT_SYMBOL_GPL(mlx4_get_devlink_port);
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/io-mapping.h> #include <linux/io-mapping.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <net/devlink.h>
#include <linux/mlx4/device.h> #include <linux/mlx4/device.h>
#include <linux/mlx4/doorbell.h> #include <linux/mlx4/doorbell.h>
...@@ -2881,8 +2882,13 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) ...@@ -2881,8 +2882,13 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
static int mlx4_init_port_info(struct mlx4_dev *dev, int port) static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
{ {
struct devlink *devlink = priv_to_devlink(mlx4_priv(dev));
struct mlx4_port_info *info = &mlx4_priv(dev)->port[port]; struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
int err = 0; int err;
err = devlink_port_register(devlink, &info->devlink_port, port);
if (err)
return err;
info->dev = dev; info->dev = dev;
info->port = port; info->port = port;
...@@ -2907,6 +2913,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) ...@@ -2907,6 +2913,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
err = device_create_file(&dev->persist->pdev->dev, &info->port_attr); err = device_create_file(&dev->persist->pdev->dev, &info->port_attr);
if (err) { if (err) {
mlx4_err(dev, "Failed to create file for port %d\n", port); mlx4_err(dev, "Failed to create file for port %d\n", port);
devlink_port_unregister(&info->devlink_port);
info->port = -1; info->port = -1;
} }
...@@ -3680,21 +3687,23 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data, ...@@ -3680,21 +3687,23 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data,
static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
struct devlink *devlink;
struct mlx4_priv *priv; struct mlx4_priv *priv;
struct mlx4_dev *dev; struct mlx4_dev *dev;
int ret; int ret;
printk_once(KERN_INFO "%s", mlx4_version); printk_once(KERN_INFO "%s", mlx4_version);
priv = kzalloc(sizeof(*priv), GFP_KERNEL); devlink = devlink_alloc(NULL, sizeof(*priv));
if (!priv) if (!devlink)
return -ENOMEM; return -ENOMEM;
priv = devlink_priv(devlink);
dev = &priv->dev; dev = &priv->dev;
dev->persist = kzalloc(sizeof(*dev->persist), GFP_KERNEL); dev->persist = kzalloc(sizeof(*dev->persist), GFP_KERNEL);
if (!dev->persist) { if (!dev->persist) {
kfree(priv); ret = -ENOMEM;
return -ENOMEM; goto err_devlink_free;
} }
dev->persist->pdev = pdev; dev->persist->pdev = pdev;
dev->persist->dev = dev; dev->persist->dev = dev;
...@@ -3703,14 +3712,23 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -3703,14 +3712,23 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
mutex_init(&dev->persist->device_state_mutex); mutex_init(&dev->persist->device_state_mutex);
mutex_init(&dev->persist->interface_state_mutex); mutex_init(&dev->persist->interface_state_mutex);
ret = devlink_register(devlink, &pdev->dev);
if (ret)
goto err_persist_free;
ret = __mlx4_init_one(pdev, id->driver_data, priv); ret = __mlx4_init_one(pdev, id->driver_data, priv);
if (ret) { if (ret)
kfree(dev->persist); goto err_devlink_unregister;
kfree(priv);
} else {
pci_save_state(pdev);
}
pci_save_state(pdev);
return 0;
err_devlink_unregister:
devlink_unregister(devlink);
err_persist_free:
kfree(dev->persist);
err_devlink_free:
devlink_free(devlink);
return ret; return ret;
} }
...@@ -3811,6 +3829,7 @@ static void mlx4_remove_one(struct pci_dev *pdev) ...@@ -3811,6 +3829,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
struct mlx4_dev *dev = persist->dev; struct mlx4_dev *dev = persist->dev;
struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_priv *priv = mlx4_priv(dev);
struct devlink *devlink = priv_to_devlink(priv);
int active_vfs = 0; int active_vfs = 0;
mutex_lock(&persist->interface_state_mutex); mutex_lock(&persist->interface_state_mutex);
...@@ -3841,8 +3860,9 @@ static void mlx4_remove_one(struct pci_dev *pdev) ...@@ -3841,8 +3860,9 @@ static void mlx4_remove_one(struct pci_dev *pdev)
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
devlink_unregister(devlink);
kfree(dev->persist); kfree(dev->persist);
kfree(priv); devlink_free(devlink);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
} }
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <net/devlink.h>
#include <linux/mlx4/device.h> #include <linux/mlx4/device.h>
#include <linux/mlx4/driver.h> #include <linux/mlx4/driver.h>
...@@ -828,6 +829,7 @@ struct mlx4_port_info { ...@@ -828,6 +829,7 @@ struct mlx4_port_info {
struct mlx4_roce_gid_table gid_table; struct mlx4_roce_gid_table gid_table;
int base_qpn; int base_qpn;
struct cpu_rmap *rmap; struct cpu_rmap *rmap;
struct devlink_port devlink_port;
}; };
struct mlx4_sense { struct mlx4_sense {
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#ifndef MLX4_DRIVER_H #ifndef MLX4_DRIVER_H
#define MLX4_DRIVER_H #define MLX4_DRIVER_H
#include <net/devlink.h>
#include <linux/mlx4/device.h> #include <linux/mlx4/device.h>
struct mlx4_dev; struct mlx4_dev;
...@@ -89,6 +90,8 @@ int mlx4_port_map_set(struct mlx4_dev *dev, struct mlx4_port_map *v2p); ...@@ -89,6 +90,8 @@ int mlx4_port_map_set(struct mlx4_dev *dev, struct mlx4_port_map *v2p);
void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port); void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port);
struct devlink_port *mlx4_get_devlink_port(struct mlx4_dev *dev, int port);
static inline u64 mlx4_mac_to_u64(u8 *addr) static inline u64 mlx4_mac_to_u64(u8 *addr)
{ {
u64 mac = 0; u64 mac = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment