Files
linux/drivers/net/ethernet/pensando/ionic/ionic_aux.c
Abhijit Gangurde 0e02faffdb net: ionic: Provide RDMA reset support for the RDMA driver
The Ethernet driver holds the privilege to execute the device commands.
Export the function to execute RDMA reset command for use by RDMA driver.

Reviewed-by: Shannon Nelson <shannon.nelson@amd.com>
Signed-off-by: Abhijit Gangurde <abhijit.gangurde@amd.com>
Link: https://patch.msgid.link/20250903061606.4139957-5-abhijit.gangurde@amd.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
2025-09-11 02:18:36 -04:00

103 lines
2.3 KiB
C

// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2018-2025, Advanced Micro Devices, Inc. */
#include <linux/kernel.h>
#include "ionic.h"
#include "ionic_lif.h"
#include "ionic_aux.h"
static DEFINE_IDA(aux_ida);
static void ionic_auxbus_release(struct device *dev)
{
struct ionic_aux_dev *ionic_adev;
ionic_adev = container_of(dev, struct ionic_aux_dev, adev.dev);
ida_free(&aux_ida, ionic_adev->adev.id);
kfree(ionic_adev);
}
int ionic_auxbus_register(struct ionic_lif *lif)
{
struct ionic_aux_dev *ionic_adev;
struct auxiliary_device *aux_dev;
int err, id;
if (!(le64_to_cpu(lif->ionic->ident.lif.capabilities) & IONIC_LIF_CAP_RDMA))
return 0;
ionic_adev = kzalloc(sizeof(*ionic_adev), GFP_KERNEL);
if (!ionic_adev)
return -ENOMEM;
aux_dev = &ionic_adev->adev;
id = ida_alloc(&aux_ida, GFP_KERNEL);
if (id < 0) {
dev_err(lif->ionic->dev, "Failed to allocate aux id: %d\n", id);
kfree(ionic_adev);
return id;
}
aux_dev->id = id;
aux_dev->name = "rdma";
aux_dev->dev.parent = &lif->ionic->pdev->dev;
aux_dev->dev.release = ionic_auxbus_release;
ionic_adev->lif = lif;
err = auxiliary_device_init(aux_dev);
if (err) {
dev_err(lif->ionic->dev, "Failed to initialize %s aux device: %d\n",
aux_dev->name, err);
ida_free(&aux_ida, id);
kfree(ionic_adev);
return err;
}
err = auxiliary_device_add(aux_dev);
if (err) {
dev_err(lif->ionic->dev, "Failed to add %s aux device: %d\n",
aux_dev->name, err);
auxiliary_device_uninit(aux_dev);
return err;
}
lif->ionic_adev = ionic_adev;
return 0;
}
void ionic_auxbus_unregister(struct ionic_lif *lif)
{
mutex_lock(&lif->adev_lock);
if (!lif->ionic_adev)
goto out;
auxiliary_device_delete(&lif->ionic_adev->adev);
auxiliary_device_uninit(&lif->ionic_adev->adev);
lif->ionic_adev = NULL;
out:
mutex_unlock(&lif->adev_lock);
}
void ionic_request_rdma_reset(struct ionic_lif *lif)
{
struct ionic *ionic = lif->ionic;
int err;
union ionic_dev_cmd cmd = {
.cmd.opcode = IONIC_CMD_RDMA_RESET_LIF,
.cmd.lif_index = cpu_to_le16(lif->index),
};
mutex_lock(&ionic->dev_cmd_lock);
ionic_dev_cmd_go(&ionic->idev, &cmd);
err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
mutex_unlock(&ionic->dev_cmd_lock);
if (err)
pr_warn("%s request_reset: error %d\n", __func__, err);
}
EXPORT_SYMBOL_NS(ionic_request_rdma_reset, "NET_IONIC");