Merge branch 'mhi-net-immutable' of https://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / net / ethernet / mellanox / mlx5 / core / sf / dev / driver.c
1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2020 Mellanox Technologies Ltd */
3
4 #include <linux/mlx5/driver.h>
5 #include <linux/mlx5/device.h>
6 #include "mlx5_core.h"
7 #include "dev.h"
8 #include "devlink.h"
9
10 static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id)
11 {
12         struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
13         struct mlx5_core_dev *mdev;
14         struct devlink *devlink;
15         int err;
16
17         devlink = mlx5_devlink_alloc();
18         if (!devlink)
19                 return -ENOMEM;
20
21         mdev = devlink_priv(devlink);
22         mdev->device = &adev->dev;
23         mdev->pdev = sf_dev->parent_mdev->pdev;
24         mdev->bar_addr = sf_dev->bar_base_addr;
25         mdev->iseg_base = sf_dev->bar_base_addr;
26         mdev->coredev_type = MLX5_COREDEV_SF;
27         mdev->priv.parent_mdev = sf_dev->parent_mdev;
28         mdev->priv.adev_idx = adev->id;
29         sf_dev->mdev = mdev;
30
31         err = mlx5_mdev_init(mdev, MLX5_DEFAULT_PROF);
32         if (err) {
33                 mlx5_core_warn(mdev, "mlx5_mdev_init on err=%d\n", err);
34                 goto mdev_err;
35         }
36
37         mdev->iseg = ioremap(mdev->iseg_base, sizeof(*mdev->iseg));
38         if (!mdev->iseg) {
39                 mlx5_core_warn(mdev, "remap error\n");
40                 goto remap_err;
41         }
42
43         err = mlx5_load_one(mdev, true);
44         if (err) {
45                 mlx5_core_warn(mdev, "mlx5_load_one err=%d\n", err);
46                 goto load_one_err;
47         }
48         return 0;
49
50 load_one_err:
51         iounmap(mdev->iseg);
52 remap_err:
53         mlx5_mdev_uninit(mdev);
54 mdev_err:
55         mlx5_devlink_free(devlink);
56         return err;
57 }
58
59 static void mlx5_sf_dev_remove(struct auxiliary_device *adev)
60 {
61         struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
62         struct devlink *devlink;
63
64         devlink = priv_to_devlink(sf_dev->mdev);
65         mlx5_unload_one(sf_dev->mdev, true);
66         iounmap(sf_dev->mdev->iseg);
67         mlx5_mdev_uninit(sf_dev->mdev);
68         mlx5_devlink_free(devlink);
69 }
70
71 static void mlx5_sf_dev_shutdown(struct auxiliary_device *adev)
72 {
73         struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
74
75         mlx5_unload_one(sf_dev->mdev, false);
76 }
77
78 static const struct auxiliary_device_id mlx5_sf_dev_id_table[] = {
79         { .name = MLX5_ADEV_NAME "." MLX5_SF_DEV_ID_NAME, },
80         { },
81 };
82
83 MODULE_DEVICE_TABLE(auxiliary, mlx5_sf_dev_id_table);
84
85 static struct auxiliary_driver mlx5_sf_driver = {
86         .name = MLX5_SF_DEV_ID_NAME,
87         .probe = mlx5_sf_dev_probe,
88         .remove = mlx5_sf_dev_remove,
89         .shutdown = mlx5_sf_dev_shutdown,
90         .id_table = mlx5_sf_dev_id_table,
91 };
92
93 int mlx5_sf_driver_register(void)
94 {
95         return auxiliary_driver_register(&mlx5_sf_driver);
96 }
97
98 void mlx5_sf_driver_unregister(void)
99 {
100         auxiliary_driver_unregister(&mlx5_sf_driver);
101 }