[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1653382572-14788-2-git-send-email-longli@linuxonhyperv.com>
Date: Tue, 24 May 2022 01:56:01 -0700
From: longli@...uxonhyperv.com
To: "K. Y. Srinivasan" <kys@...rosoft.com>,
Haiyang Zhang <haiyangz@...rosoft.com>,
Stephen Hemminger <sthemmin@...rosoft.com>,
Wei Liu <wei.liu@...nel.org>, Dexuan Cui <decui@...rosoft.com>,
"David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Jason Gunthorpe <jgg@...pe.ca>,
Leon Romanovsky <leon@...nel.org>,
Ajay Sharma <sharmaajay@...rosoft.com>
Cc: linux-hyperv@...r.kernel.org, netdev@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-rdma@...r.kernel.org,
Long Li <longli@...rosoft.com>
Subject: [Patch v2 01/12] net: mana: Add support for auxiliary device
From: Long Li <longli@...rosoft.com>
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.
Signed-off-by: Long Li <longli@...rosoft.com>
---
drivers/net/ethernet/microsoft/mana/gdma.h | 2 +
drivers/net/ethernet/microsoft/mana/mana.h | 6 ++
drivers/net/ethernet/microsoft/mana/mana_en.c | 83 ++++++++++++++++++-
3 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/microsoft/mana/gdma.h b/drivers/net/ethernet/microsoft/mana/gdma.h
index 41ecd156e95f..d815d323be87 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma.h
+++ b/drivers/net/ethernet/microsoft/mana/gdma.h
@@ -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.h b/drivers/net/ethernet/microsoft/mana/mana.h
index d36405af9432..51bff91b63ee 100644
--- a/drivers/net/ethernet/microsoft/mana/mana.h
+++ b/drivers/net/ethernet/microsoft/mana/mana.h
@@ -6,6 +6,7 @@
#include "gdma.h"
#include "hw_channel.h"
+#include <linux/auxiliary_bus.h>
/* Microsoft Azure Network Adapter (MANA)'s definitions
*
@@ -561,4 +562,9 @@ struct mana_tx_package {
struct gdma_posted_wqe_info wqe_info;
};
+struct mana_adev {
+ struct auxiliary_device adev;
+ struct gdma_dev *mdev;
+};
+
#endif /* _MANA_H */
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index b7d3ba1b4d17..c706bf943e49 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -13,6 +13,18 @@
#include "mana.h"
+static DEFINE_IDA(mana_adev_ida);
+
+int mana_adev_idx_alloc(void)
+{
+ return ida_alloc(&mana_adev_ida, GFP_KERNEL);
+}
+
+void mana_adev_idx_free(int idx)
+{
+ ida_free(&mana_adev_ida, idx);
+}
+
/* Microsoft Azure Network Adapter (MANA) functions */
static int mana_open(struct net_device *ndev)
@@ -1960,6 +1972,70 @@ static int mana_probe_port(struct mana_context *ac, int port_idx,
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)
+{
+ int ret = 0;
+ struct mana_adev *madev;
+ struct auxiliary_device *adev;
+
+ madev = kzalloc(sizeof(*madev), GFP_KERNEL);
+ if (!madev)
+ return -ENOMEM;
+
+ adev = &madev->adev;
+ adev->id = mana_adev_idx_alloc();
+ if (adev->id < 0) {
+ ret = adev->id;
+ goto idx_fail;
+ }
+
+ 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;
@@ -2027,6 +2103,8 @@ int mana_probe(struct gdma_dev *gd, bool resuming)
break;
}
}
+
+ err = add_adev(gd);
out:
if (err)
mana_remove(gd, false);
@@ -2043,6 +2121,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) {
@@ -2075,7 +2157,6 @@ void mana_remove(struct gdma_dev *gd, bool suspending)
}
mana_destroy_eq(ac);
-
out:
mana_gd_deregister_device(gd);
--
2.17.1
Powered by blists - more mailing lists