linux/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
<<
>>
Prefs
   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
  10static 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(&adev->dev);
  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                err = -ENOMEM;
  41                goto remap_err;
  42        }
  43
  44        err = mlx5_init_one(mdev);
  45        if (err) {
  46                mlx5_core_warn(mdev, "mlx5_init_one err=%d\n", err);
  47                goto init_one_err;
  48        }
  49        devlink_reload_enable(devlink);
  50        return 0;
  51
  52init_one_err:
  53        iounmap(mdev->iseg);
  54remap_err:
  55        mlx5_mdev_uninit(mdev);
  56mdev_err:
  57        mlx5_devlink_free(devlink);
  58        return err;
  59}
  60
  61static void mlx5_sf_dev_remove(struct auxiliary_device *adev)
  62{
  63        struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
  64        struct devlink *devlink;
  65
  66        devlink = priv_to_devlink(sf_dev->mdev);
  67        devlink_reload_disable(devlink);
  68        mlx5_uninit_one(sf_dev->mdev);
  69        iounmap(sf_dev->mdev->iseg);
  70        mlx5_mdev_uninit(sf_dev->mdev);
  71        mlx5_devlink_free(devlink);
  72}
  73
  74static void mlx5_sf_dev_shutdown(struct auxiliary_device *adev)
  75{
  76        struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
  77
  78        mlx5_unload_one(sf_dev->mdev);
  79}
  80
  81static const struct auxiliary_device_id mlx5_sf_dev_id_table[] = {
  82        { .name = MLX5_ADEV_NAME "." MLX5_SF_DEV_ID_NAME, },
  83        { },
  84};
  85
  86MODULE_DEVICE_TABLE(auxiliary, mlx5_sf_dev_id_table);
  87
  88static struct auxiliary_driver mlx5_sf_driver = {
  89        .name = MLX5_SF_DEV_ID_NAME,
  90        .probe = mlx5_sf_dev_probe,
  91        .remove = mlx5_sf_dev_remove,
  92        .shutdown = mlx5_sf_dev_shutdown,
  93        .id_table = mlx5_sf_dev_id_table,
  94};
  95
  96int mlx5_sf_driver_register(void)
  97{
  98        return auxiliary_driver_register(&mlx5_sf_driver);
  99}
 100
 101void mlx5_sf_driver_unregister(void)
 102{
 103        auxiliary_driver_unregister(&mlx5_sf_driver);
 104}
 105