mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
modules/mqnic: Add initial devlink support
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
parent
2d975c1e83
commit
a9800099e3
@ -6,6 +6,7 @@ ifneq ($(KERNELRELEASE),)
|
|||||||
# object files to build
|
# object files to build
|
||||||
obj-m += mqnic.o
|
obj-m += mqnic.o
|
||||||
mqnic-y += mqnic_main.o
|
mqnic-y += mqnic_main.o
|
||||||
|
mqnic-y += mqnic_devlink.o
|
||||||
mqnic-y += mqnic_res.o
|
mqnic-y += mqnic_res.o
|
||||||
mqnic-y += mqnic_reg_block.o
|
mqnic-y += mqnic_reg_block.o
|
||||||
mqnic-y += mqnic_irq.o
|
mqnic-y += mqnic_irq.o
|
||||||
|
@ -467,6 +467,10 @@ struct mqnic_priv {
|
|||||||
|
|
||||||
// mqnic_main.c
|
// mqnic_main.c
|
||||||
|
|
||||||
|
// mqnic_devlink.c
|
||||||
|
struct devlink *mqnic_devlink_alloc(struct device *dev);
|
||||||
|
void mqnic_devlink_free(struct devlink *devlink);
|
||||||
|
|
||||||
// mqnic_res.c
|
// mqnic_res.c
|
||||||
struct mqnic_res *mqnic_create_res(unsigned int count, u8 __iomem *base, unsigned int stride);
|
struct mqnic_res *mqnic_create_res(unsigned int count, u8 __iomem *base, unsigned int stride);
|
||||||
void mqnic_destroy_res(struct mqnic_res *res);
|
void mqnic_destroy_res(struct mqnic_res *res);
|
||||||
|
100
modules/mqnic/mqnic_devlink.c
Normal file
100
modules/mqnic/mqnic_devlink.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// SPDX-License-Identifier: BSD-2-Clause-Views
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 The Regents of the University of California
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mqnic.h"
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include <net/devlink.h>
|
||||||
|
|
||||||
|
static int mqnic_devlink_info_get(struct devlink *devlink,
|
||||||
|
struct devlink_info_req *req, struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
struct mqnic_dev *mdev = devlink_priv(devlink);
|
||||||
|
char str[32];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)
|
||||||
|
err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
snprintf(str, sizeof(str), "%08x", mdev->fpga_id);
|
||||||
|
|
||||||
|
err = devlink_info_version_fixed_put(req, "fpga.id", str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snprintf(str, sizeof(str), "%08x", mdev->board_id);
|
||||||
|
|
||||||
|
err = devlink_info_version_fixed_put(req, DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snprintf(str, sizeof(str), "%d.%d.%d.%d",
|
||||||
|
mdev->board_ver >> 24, (mdev->board_ver >> 16) & 0xff,
|
||||||
|
(mdev->board_ver >> 8) & 0xff, mdev->board_ver & 0xff);
|
||||||
|
|
||||||
|
err = devlink_info_version_fixed_put(req, DEVLINK_INFO_VERSION_GENERIC_BOARD_REV, str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snprintf(str, sizeof(str), "%08x", mdev->fw_id);
|
||||||
|
|
||||||
|
err = devlink_info_version_running_put(req, "fw.id", str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snprintf(str, sizeof(str), "%d.%d.%d.%d",
|
||||||
|
mdev->fw_ver >> 24, (mdev->fw_ver >> 16) & 0xff,
|
||||||
|
(mdev->fw_ver >> 8) & 0xff, mdev->fw_ver & 0xff);
|
||||||
|
|
||||||
|
err = devlink_info_version_running_put(req, "fw.version", str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
err = devlink_info_version_running_put(req, DEVLINK_INFO_VERSION_GENERIC_FW, str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = devlink_info_version_running_put(req, "fw.build_date", mdev->build_date_str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snprintf(str, sizeof(str), "%08x", mdev->git_hash);
|
||||||
|
|
||||||
|
err = devlink_info_version_running_put(req, "fw.git_hash", str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snprintf(str, sizeof(str), "%08x", mdev->rel_info);
|
||||||
|
|
||||||
|
err = devlink_info_version_running_put(req, "fw.rel_info", str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (mdev->app_id) {
|
||||||
|
snprintf(str, sizeof(str), "%08x", mdev->app_id);
|
||||||
|
|
||||||
|
err = devlink_info_version_running_put(req, "fw.app.id", str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct devlink_ops mqnic_devlink_ops = {
|
||||||
|
.info_get = mqnic_devlink_info_get,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct devlink *mqnic_devlink_alloc(struct device *dev)
|
||||||
|
{
|
||||||
|
return devlink_alloc(&mqnic_devlink_ops, sizeof(struct mqnic_dev), dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqnic_devlink_free(struct devlink *devlink)
|
||||||
|
{
|
||||||
|
devlink_free(devlink);
|
||||||
|
}
|
@ -9,6 +9,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/reset.h>
|
#include <linux/reset.h>
|
||||||
#include <linux/rtc.h>
|
#include <linux/rtc.h>
|
||||||
|
#include <net/devlink.h>
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
|
||||||
#include <linux/pci-aspm.h>
|
#include <linux/pci-aspm.h>
|
||||||
@ -238,6 +239,7 @@ static void mqnic_adev_release(struct device *dev)
|
|||||||
static int mqnic_common_probe(struct mqnic_dev *mqnic)
|
static int mqnic_common_probe(struct mqnic_dev *mqnic)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
struct devlink *devlink = priv_to_devlink(mqnic);
|
||||||
struct device *dev = mqnic->dev;
|
struct device *dev = mqnic->dev;
|
||||||
struct mqnic_reg_block *rb;
|
struct mqnic_reg_block *rb;
|
||||||
struct rtc_time tm;
|
struct rtc_time tm;
|
||||||
@ -442,6 +444,7 @@ fail_create_if:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// probe complete
|
// probe complete
|
||||||
|
devlink_register(devlink);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// error handling
|
// error handling
|
||||||
@ -458,8 +461,11 @@ fail_rb_init:
|
|||||||
|
|
||||||
static void mqnic_common_remove(struct mqnic_dev *mqnic)
|
static void mqnic_common_remove(struct mqnic_dev *mqnic)
|
||||||
{
|
{
|
||||||
|
struct devlink *devlink = priv_to_devlink(mqnic);
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
|
devlink_unregister(devlink);
|
||||||
|
|
||||||
#ifdef CONFIG_AUXILIARY_BUS
|
#ifdef CONFIG_AUXILIARY_BUS
|
||||||
if (mqnic->app_adev) {
|
if (mqnic->app_adev) {
|
||||||
auxiliary_device_delete(&mqnic->app_adev->adev);
|
auxiliary_device_delete(&mqnic->app_adev->adev);
|
||||||
@ -494,6 +500,7 @@ static int mqnic_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct mqnic_dev *mqnic;
|
struct mqnic_dev *mqnic;
|
||||||
|
struct devlink *devlink;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct pci_dev *bridge = pci_upstream_bridge(pdev);
|
struct pci_dev *bridge = pci_upstream_bridge(pdev);
|
||||||
|
|
||||||
@ -563,10 +570,11 @@ static int mqnic_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent
|
|||||||
pcie_print_link_status(pdev);
|
pcie_print_link_status(pdev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mqnic = devm_kzalloc(dev, sizeof(*mqnic), GFP_KERNEL);
|
devlink = mqnic_devlink_alloc(dev);
|
||||||
if (!mqnic)
|
if (!devlink)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mqnic = devlink_priv(devlink);
|
||||||
mqnic->dev = dev;
|
mqnic->dev = dev;
|
||||||
mqnic->pdev = pdev;
|
mqnic->pdev = pdev;
|
||||||
pci_set_drvdata(pdev, mqnic);
|
pci_set_drvdata(pdev, mqnic);
|
||||||
@ -676,12 +684,14 @@ fail_regions:
|
|||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
fail_enable_device:
|
fail_enable_device:
|
||||||
mqnic_free_id(mqnic);
|
mqnic_free_id(mqnic);
|
||||||
|
mqnic_devlink_free(devlink);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mqnic_pci_remove(struct pci_dev *pdev)
|
static void mqnic_pci_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct mqnic_dev *mqnic = pci_get_drvdata(pdev);
|
struct mqnic_dev *mqnic = pci_get_drvdata(pdev);
|
||||||
|
struct devlink *devlink = priv_to_devlink(mqnic);
|
||||||
|
|
||||||
dev_info(&pdev->dev, DRIVER_NAME " PCI remove");
|
dev_info(&pdev->dev, DRIVER_NAME " PCI remove");
|
||||||
|
|
||||||
@ -698,6 +708,7 @@ static void mqnic_pci_remove(struct pci_dev *pdev)
|
|||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
mqnic_free_id(mqnic);
|
mqnic_free_id(mqnic);
|
||||||
|
mqnic_devlink_free(devlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mqnic_pci_shutdown(struct pci_dev *pdev)
|
static void mqnic_pci_shutdown(struct pci_dev *pdev)
|
||||||
@ -720,6 +731,7 @@ static int mqnic_platform_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct mqnic_dev *mqnic;
|
struct mqnic_dev *mqnic;
|
||||||
|
struct devlink *devlink;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct reset_control *rst;
|
struct reset_control *rst;
|
||||||
@ -730,10 +742,11 @@ static int mqnic_platform_probe(struct platform_device *pdev)
|
|||||||
dev_info(dev, " NUMA node: %d", pdev->dev.numa_node);
|
dev_info(dev, " NUMA node: %d", pdev->dev.numa_node);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mqnic = devm_kzalloc(dev, sizeof(*mqnic), GFP_KERNEL);
|
devlink = mqnic_devlink_alloc(dev);
|
||||||
if (!mqnic)
|
if (!devlink)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mqnic = devlink_priv(devlink);
|
||||||
mqnic->dev = dev;
|
mqnic->dev = dev;
|
||||||
mqnic->pfdev = pdev;
|
mqnic->pfdev = pdev;
|
||||||
platform_set_drvdata(pdev, mqnic);
|
platform_set_drvdata(pdev, mqnic);
|
||||||
@ -822,18 +835,21 @@ static int mqnic_platform_probe(struct platform_device *pdev)
|
|||||||
// error handling
|
// error handling
|
||||||
fail:
|
fail:
|
||||||
mqnic_free_id(mqnic);
|
mqnic_free_id(mqnic);
|
||||||
|
mqnic_devlink_free(devlink);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mqnic_platform_remove(struct platform_device *pdev)
|
static int mqnic_platform_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct mqnic_dev *mqnic = platform_get_drvdata(pdev);
|
struct mqnic_dev *mqnic = platform_get_drvdata(pdev);
|
||||||
|
struct devlink *devlink = priv_to_devlink(mqnic);
|
||||||
|
|
||||||
dev_info(&pdev->dev, DRIVER_NAME " platform remove");
|
dev_info(&pdev->dev, DRIVER_NAME " platform remove");
|
||||||
|
|
||||||
mqnic_common_remove(mqnic);
|
mqnic_common_remove(mqnic);
|
||||||
|
|
||||||
mqnic_free_id(mqnic);
|
mqnic_free_id(mqnic);
|
||||||
|
mqnic_devlink_free(devlink);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user