[PATCH 03/34] net: mana: Add support for auxiliary device
authorLong Li <longli@microsoft.com>
Thu, 3 Nov 2022 19:16:19 +0000 (12:16 -0700)
committerSalvatore Bonaccorso <carnil@debian.org>
Fri, 1 Nov 2024 04:23:37 +0000 (05:23 +0100)
In preparation for supporting MANA RDMA driver, add support for auxiliary
device in the Ethernet driver. The RDMA device is modeled as an auxiliary
device to the Ethernet device.

Reviewed-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Long Li <longli@microsoft.com>
Link: https://lore.kernel.org/r/1667502990-2559-2-git-send-email-longli@linuxonhyperv.com
Acked-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
(cherry picked from commit a69839d4327d053b18d8e1b0e7ddeee78db78f4f)
Signed-off-by: Bastian Blank <waldi@debian.org>
Gbp-Pq: Topic features/all/ethernet-microsoft
Gbp-Pq: Name 0003-net-mana-Add-support-for-auxiliary-device.patch

drivers/net/ethernet/microsoft/Kconfig
drivers/net/ethernet/microsoft/mana/gdma.h
drivers/net/ethernet/microsoft/mana/mana_auxiliary.h [new file with mode: 0644]
drivers/net/ethernet/microsoft/mana/mana_en.c

index 8b6c4cc37c53c63221aa2c42a96fc405a64538ab..01eb7445ead9517b66d2c9ae1e0dcb987c1eb58d 100644 (file)
@@ -19,6 +19,7 @@ config MICROSOFT_MANA
        tristate "Microsoft Azure Network Adapter (MANA) support"
        depends on PCI_MSI && X86_64
        depends on PCI_HYPERV
+       select AUXILIARY_BUS
        select PAGE_POOL
        help
          This driver supports Microsoft Azure Network Adapter (MANA).
index 68684a8bcead508f9797b68ed7aa98df49e59d71..df0ffe35db92b9dfbde0b2651d0285b2a318f576 100644 (file)
@@ -204,6 +204,8 @@ struct gdma_dev {
 
        /* GDMA driver specific pointer */
        void *driver_data;
+
+       struct auxiliary_device *adev;
 };
 
 #define MINIMUM_SUPPORTED_PAGE_SIZE PAGE_SIZE
diff --git a/drivers/net/ethernet/microsoft/mana/mana_auxiliary.h b/drivers/net/ethernet/microsoft/mana/mana_auxiliary.h
new file mode 100644 (file)
index 0000000..373d597
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2022, Microsoft Corporation. */
+
+#include "mana.h"
+#include <linux/auxiliary_bus.h>
+
+struct mana_adev {
+       struct auxiliary_device adev;
+       struct gdma_dev *mdev;
+};
index 8bf4919dc960f27ad07119fe68b3554ad27d8008..4c14a4e1518870bea89591f3c52b704b8aa083dc 100644 (file)
 #include <net/ip6_checksum.h>
 
 #include "mana.h"
+#include "mana_auxiliary.h"
+
+static DEFINE_IDA(mana_adev_ida);
+
+static int mana_adev_idx_alloc(void)
+{
+       return ida_alloc(&mana_adev_ida, GFP_KERNEL);
+}
+
+static void mana_adev_idx_free(int idx)
+{
+       ida_free(&mana_adev_ida, idx);
+}
 
 /* Microsoft Azure Network Adapter (MANA) functions */
 
@@ -2155,6 +2168,69 @@ free_net:
        return err;
 }
 
+static void adev_release(struct device *dev)
+{
+       struct mana_adev *madev = container_of(dev, struct mana_adev, adev.dev);
+
+       kfree(madev);
+}
+
+static void remove_adev(struct gdma_dev *gd)
+{
+       struct auxiliary_device *adev = gd->adev;
+       int id = adev->id;
+
+       auxiliary_device_delete(adev);
+       auxiliary_device_uninit(adev);
+
+       mana_adev_idx_free(id);
+       gd->adev = NULL;
+}
+
+static int add_adev(struct gdma_dev *gd)
+{
+       struct auxiliary_device *adev;
+       struct mana_adev *madev;
+       int ret;
+
+       madev = kzalloc(sizeof(*madev), GFP_KERNEL);
+       if (!madev)
+               return -ENOMEM;
+
+       adev = &madev->adev;
+       ret = mana_adev_idx_alloc();
+       if (ret < 0)
+               goto idx_fail;
+       adev->id = ret;
+
+       adev->name = "rdma";
+       adev->dev.parent = gd->gdma_context->dev;
+       adev->dev.release = adev_release;
+       madev->mdev = gd;
+
+       ret = auxiliary_device_init(adev);
+       if (ret)
+               goto init_fail;
+
+       ret = auxiliary_device_add(adev);
+       if (ret)
+               goto add_fail;
+
+       gd->adev = adev;
+       return 0;
+
+add_fail:
+       auxiliary_device_uninit(adev);
+
+init_fail:
+       mana_adev_idx_free(adev->id);
+
+idx_fail:
+       kfree(madev);
+
+       return ret;
+}
+
 int mana_probe(struct gdma_dev *gd, bool resuming)
 {
        struct gdma_context *gc = gd->gdma_context;
@@ -2222,6 +2298,8 @@ int mana_probe(struct gdma_dev *gd, bool resuming)
                                break;
                }
        }
+
+       err = add_adev(gd);
 out:
        if (err)
                mana_remove(gd, false);
@@ -2238,6 +2316,10 @@ void mana_remove(struct gdma_dev *gd, bool suspending)
        int err;
        int i;
 
+       /* adev currently doesn't support suspending, always remove it */
+       if (gd->adev)
+               remove_adev(gd);
+
        for (i = 0; i < ac->num_ports; i++) {
                ndev = ac->ports[i];
                if (!ndev) {
@@ -2270,7 +2352,6 @@ void mana_remove(struct gdma_dev *gd, bool suspending)
        }
 
        mana_destroy_eq(ac);
-
 out:
        mana_gd_deregister_device(gd);