From: Gage Eads <gage.eads@intel.com>
To: linux-kernel@vger.kernel.org, arnd@arndb.de, gregkh@linuxfoundation.org
Cc: magnus.karlsson@intel.com, bjorn.topel@intel.com
Subject: [PATCH 02/20] dlb2: initialize PF device
Date: Sun, 12 Jul 2020 08:43:13 -0500 [thread overview]
Message-ID: <20200712134331.8169-3-gage.eads@intel.com> (raw)
In-Reply-To: <20200712134331.8169-1-gage.eads@intel.com>
The driver detects the device type (PF/VF) at probe time, and assigns the
corresponding 'ops' callbacks from that. These callbacks include mapping
and unmapping the PCI BAR space, creating/destroying the device, and
adding/deleting a char device.
Signed-off-by: Gage Eads <gage.eads@intel.com>
Reviewed-by: Magnus Karlsson <magnus.karlsson@intel.com>
---
drivers/misc/dlb2/Makefile | 5 +-
drivers/misc/dlb2/dlb2_hw_types.h | 28 ++++++++
drivers/misc/dlb2/dlb2_main.c | 49 ++++++++++++-
drivers/misc/dlb2/dlb2_main.h | 30 ++++++++
drivers/misc/dlb2/dlb2_pf_ops.c | 140 ++++++++++++++++++++++++++++++++++++++
5 files changed, 249 insertions(+), 3 deletions(-)
create mode 100644 drivers/misc/dlb2/dlb2_pf_ops.c
diff --git a/drivers/misc/dlb2/Makefile b/drivers/misc/dlb2/Makefile
index 90ae953d2a8f..95e67e5bd8ff 100644
--- a/drivers/misc/dlb2/Makefile
+++ b/drivers/misc/dlb2/Makefile
@@ -4,5 +4,6 @@
obj-$(CONFIG_INTEL_DLB2) := dlb2.o
-dlb2-objs := \
- dlb2_main.o \
+dlb2-objs := \
+ dlb2_main.o \
+ dlb2_pf_ops.o \
diff --git a/drivers/misc/dlb2/dlb2_hw_types.h b/drivers/misc/dlb2/dlb2_hw_types.h
index 558099db50b8..860d81bf3103 100644
--- a/drivers/misc/dlb2/dlb2_hw_types.h
+++ b/drivers/misc/dlb2/dlb2_hw_types.h
@@ -5,6 +5,25 @@
#ifndef __DLB2_HW_TYPES_H
#define __DLB2_HW_TYPES_H
+#include <linux/io.h>
+
+#define DLB2_PCI_REG_READ(addr) ioread32(addr)
+#define DLB2_PCI_REG_WRITE(reg, value) iowrite32(value, reg)
+
+/* Read/write register 'reg' in the CSR BAR space */
+#define DLB2_CSR_REG_ADDR(a, reg) ((a)->csr_kva + (reg))
+#define DLB2_CSR_RD(hw, reg) \
+ DLB2_PCI_REG_READ(DLB2_CSR_REG_ADDR((hw), (reg)))
+#define DLB2_CSR_WR(hw, reg, value) \
+ DLB2_PCI_REG_WRITE(DLB2_CSR_REG_ADDR((hw), (reg)), (value))
+
+/* Read/write register 'reg' in the func BAR space */
+#define DLB2_FUNC_REG_ADDR(a, reg) ((a)->func_kva + (reg))
+#define DLB2_FUNC_RD(hw, reg) \
+ DLB2_PCI_REG_READ(DLB2_FUNC_REG_ADDR((hw), (reg)))
+#define DLB2_FUNC_WR(hw, reg, value) \
+ DLB2_PCI_REG_WRITE(DLB2_FUNC_REG_ADDR((hw), (reg)), (value))
+
#define DLB2_MAX_NUM_VDEVS 16
#define DLB2_MAX_NUM_DOMAINS 32
#define DLB2_MAX_NUM_LDB_QUEUES 32 /* LDB == load-balanced */
@@ -26,4 +45,13 @@
#define DLB2_MAX_QID_EMPTY_CHECK_LOOPS (32 * 64 * 1024 * (800 / 30))
#define DLB2_HZ 800000000
+struct dlb2_hw {
+ /* BAR 0 address */
+ void __iomem *csr_kva;
+ unsigned long csr_phys_addr;
+ /* BAR 2 address */
+ void __iomem *func_kva;
+ unsigned long func_phys_addr;
+};
+
#endif /* __DLB2_HW_TYPES_H */
diff --git a/drivers/misc/dlb2/dlb2_main.c b/drivers/misc/dlb2/dlb2_main.c
index fd953a1c4cb5..d6fb46c05985 100644
--- a/drivers/misc/dlb2/dlb2_main.c
+++ b/drivers/misc/dlb2/dlb2_main.c
@@ -51,6 +51,18 @@ static const struct file_operations dlb2_fops = {
/****** PCI driver callbacks ******/
/**********************************/
+static void dlb2_assign_ops(struct dlb2_dev *dlb2_dev,
+ const struct pci_device_id *pdev_id)
+{
+ dlb2_dev->type = pdev_id->driver_data;
+
+ switch (pdev_id->driver_data) {
+ case DLB2_PF:
+ dlb2_dev->ops = &dlb2_pf_ops;
+ break;
+ }
+}
+
static DEFINE_IDA(dlb2_ids);
static int dlb2_alloc_id(void)
@@ -75,6 +87,8 @@ static int dlb2_probe(struct pci_dev *pdev,
if (!dlb2_dev)
return -ENOMEM;
+ dlb2_assign_ops(dlb2_dev, pdev_id);
+
pci_set_drvdata(pdev, dlb2_dev);
dlb2_dev->pdev = pdev;
@@ -107,12 +121,39 @@ static int dlb2_probe(struct pci_dev *pdev,
if (pci_enable_pcie_error_reporting(pdev))
dev_info(&pdev->dev, "[%s()] Failed to enable AER\n", __func__);
+ ret = dlb2_dev->ops->map_pci_bar_space(dlb2_dev, pdev);
+ if (ret)
+ goto map_pci_bar_fail;
+
+ ret = dlb2_dev->ops->cdev_add(dlb2_dev,
+ dlb2_dev_number_base,
+ &dlb2_fops);
+ if (ret)
+ goto cdev_add_fail;
+
+ ret = dlb2_dev->ops->device_create(dlb2_dev, pdev, dlb2_class);
+ if (ret)
+ goto device_add_fail;
+
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+ if (ret)
+ goto dma_set_mask_fail;
+
mutex_lock(&dlb2_driver_lock);
list_add(&dlb2_dev->list, &dlb2_dev_list);
mutex_unlock(&dlb2_driver_lock);
return 0;
+dma_set_mask_fail:
+ dlb2_dev->ops->device_destroy(dlb2_dev, dlb2_class);
+device_add_fail:
+ dlb2_dev->ops->cdev_del(dlb2_dev);
+cdev_add_fail:
+ dlb2_dev->ops->unmap_pci_bar_space(dlb2_dev, pdev);
+map_pci_bar_fail:
+ pci_disable_pcie_error_reporting(pdev);
+ pci_release_regions(pdev);
pci_request_regions_fail:
pci_disable_device(pdev);
pci_enable_device_fail:
@@ -134,6 +175,12 @@ static void dlb2_remove(struct pci_dev *pdev)
list_del(&dlb2_dev->list);
mutex_unlock(&dlb2_driver_lock);
+ dlb2_dev->ops->device_destroy(dlb2_dev, dlb2_class);
+
+ dlb2_dev->ops->cdev_del(dlb2_dev);
+
+ dlb2_dev->ops->unmap_pci_bar_space(dlb2_dev, pdev);
+
pci_disable_pcie_error_reporting(pdev);
pci_release_regions(pdev);
@@ -146,7 +193,7 @@ static void dlb2_remove(struct pci_dev *pdev)
}
static struct pci_device_id dlb2_id_table[] = {
- { PCI_DEVICE_DATA(INTEL, DLB2_PF, NULL) },
+ { PCI_DEVICE_DATA(INTEL, DLB2_PF, DLB2_PF) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, dlb2_id_table);
diff --git a/drivers/misc/dlb2/dlb2_main.h b/drivers/misc/dlb2/dlb2_main.h
index cf3d37b0f0ae..5e35d1e7c251 100644
--- a/drivers/misc/dlb2/dlb2_main.h
+++ b/drivers/misc/dlb2/dlb2_main.h
@@ -28,10 +28,40 @@ static const char dlb2_driver_name[] = KBUILD_MODNAME;
#define DLB2_NUM_FUNCS_PER_DEVICE (1 + DLB2_MAX_NUM_VDEVS)
#define DLB2_MAX_NUM_DEVICES (DLB2_MAX_NUM_PFS * DLB2_NUM_FUNCS_PER_DEVICE)
+enum dlb2_device_type {
+ DLB2_PF,
+ DLB2_VF,
+};
+
+struct dlb2_dev;
+
+struct dlb2_device_ops {
+ int (*map_pci_bar_space)(struct dlb2_dev *dev, struct pci_dev *pdev);
+ void (*unmap_pci_bar_space)(struct dlb2_dev *dev,
+ struct pci_dev *pdev);
+ int (*device_create)(struct dlb2_dev *dlb2_dev,
+ struct pci_dev *pdev,
+ struct class *dlb2_class);
+ void (*device_destroy)(struct dlb2_dev *dlb2_dev,
+ struct class *dlb2_class);
+ int (*cdev_add)(struct dlb2_dev *dlb2_dev,
+ dev_t base,
+ const struct file_operations *fops);
+ void (*cdev_del)(struct dlb2_dev *dlb2_dev);
+};
+
+extern struct dlb2_device_ops dlb2_pf_ops;
+
struct dlb2_dev {
struct pci_dev *pdev;
+ struct dlb2_hw hw;
+ struct cdev cdev;
+ struct dlb2_device_ops *ops;
struct list_head list;
+ struct device *dlb2_device;
+ enum dlb2_device_type type;
int id;
+ dev_t dev_number;
};
#endif /* __DLB2_MAIN_H */
diff --git a/drivers/misc/dlb2/dlb2_pf_ops.c b/drivers/misc/dlb2/dlb2_pf_ops.c
new file mode 100644
index 000000000000..14a50a778675
--- /dev/null
+++ b/drivers/misc/dlb2/dlb2_pf_ops.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2017-2020 Intel Corporation */
+
+#include "dlb2_main.h"
+
+/********************************/
+/****** PCI BAR management ******/
+/********************************/
+
+static void
+dlb2_pf_unmap_pci_bar_space(struct dlb2_dev *dlb2_dev,
+ struct pci_dev *pdev)
+{
+ pci_iounmap(pdev, dlb2_dev->hw.csr_kva);
+ pci_iounmap(pdev, dlb2_dev->hw.func_kva);
+}
+
+static int
+dlb2_pf_map_pci_bar_space(struct dlb2_dev *dlb2_dev,
+ struct pci_dev *pdev)
+{
+ /* BAR 0: PF FUNC BAR space */
+ dlb2_dev->hw.func_kva = pci_iomap(pdev, 0, 0);
+ dlb2_dev->hw.func_phys_addr = pci_resource_start(pdev, 0);
+
+ if (!dlb2_dev->hw.func_kva) {
+ dev_err(&pdev->dev, "Cannot iomap BAR 0 (size %llu)\n",
+ pci_resource_len(pdev, 0));
+
+ return -EIO;
+ }
+
+ dev_dbg(&pdev->dev, "BAR 0 iomem base: %p\n",
+ dlb2_dev->hw.func_kva);
+ dev_dbg(&pdev->dev, "BAR 0 start: 0x%llx\n",
+ pci_resource_start(pdev, 0));
+ dev_dbg(&pdev->dev, "BAR 0 len: %llu\n",
+ pci_resource_len(pdev, 0));
+
+ /* BAR 2: PF CSR BAR space */
+ dlb2_dev->hw.csr_kva = pci_iomap(pdev, 2, 0);
+ dlb2_dev->hw.csr_phys_addr = pci_resource_start(pdev, 2);
+
+ if (!dlb2_dev->hw.csr_kva) {
+ dev_err(&pdev->dev, "Cannot iomap BAR 2 (size %llu)\n",
+ pci_resource_len(pdev, 2));
+
+ pci_iounmap(pdev, dlb2_dev->hw.func_kva);
+ return -EIO;
+ }
+
+ dev_dbg(&pdev->dev, "BAR 2 iomem base: %p\n",
+ dlb2_dev->hw.csr_kva);
+ dev_dbg(&pdev->dev, "BAR 2 start: 0x%llx\n",
+ pci_resource_start(pdev, 2));
+ dev_dbg(&pdev->dev, "BAR 2 len: %llu\n",
+ pci_resource_len(pdev, 2));
+
+ return 0;
+}
+
+/*******************************/
+/****** Driver management ******/
+/*******************************/
+
+static int
+dlb2_pf_cdev_add(struct dlb2_dev *dlb2_dev,
+ dev_t base,
+ const struct file_operations *fops)
+{
+ int ret;
+
+ dlb2_dev->dev_number = MKDEV(MAJOR(base), MINOR(base) + dlb2_dev->id);
+
+ cdev_init(&dlb2_dev->cdev, fops);
+
+ dlb2_dev->cdev.dev = dlb2_dev->dev_number;
+ dlb2_dev->cdev.owner = THIS_MODULE;
+
+ ret = cdev_add(&dlb2_dev->cdev, dlb2_dev->cdev.dev, 1);
+ if (ret < 0)
+ dev_err(dlb2_dev->dlb2_device,
+ "%s: cdev_add() returned %d\n",
+ dlb2_driver_name, ret);
+
+ return ret;
+}
+
+static void
+dlb2_pf_cdev_del(struct dlb2_dev *dlb2_dev)
+{
+ cdev_del(&dlb2_dev->cdev);
+}
+
+static int
+dlb2_pf_device_create(struct dlb2_dev *dlb2_dev,
+ struct pci_dev *pdev,
+ struct class *dlb2_class)
+{
+ /*
+ * Create a new device in order to create a /dev/dlb node. This device
+ * is a child of the DLB PCI device.
+ */
+ dlb2_dev->dlb2_device = device_create(dlb2_class,
+ &pdev->dev,
+ dlb2_dev->dev_number,
+ dlb2_dev,
+ "dlb%d",
+ dlb2_dev->id);
+
+ if (IS_ERR(dlb2_dev->dlb2_device)) {
+ dev_err(&pdev->dev,
+ "%s: device_create() returned %ld\n",
+ dlb2_driver_name, PTR_ERR(dlb2_dev->dlb2_device));
+
+ return PTR_ERR(dlb2_dev->dlb2_device);
+ }
+
+ return 0;
+}
+
+static void
+dlb2_pf_device_destroy(struct dlb2_dev *dlb2_dev,
+ struct class *dlb2_class)
+{
+ device_destroy(dlb2_class, dlb2_dev->dev_number);
+}
+
+/********************************/
+/****** DLB2 PF Device Ops ******/
+/********************************/
+
+struct dlb2_device_ops dlb2_pf_ops = {
+ .map_pci_bar_space = dlb2_pf_map_pci_bar_space,
+ .unmap_pci_bar_space = dlb2_pf_unmap_pci_bar_space,
+ .device_create = dlb2_pf_device_create,
+ .device_destroy = dlb2_pf_device_destroy,
+ .cdev_add = dlb2_pf_cdev_add,
+ .cdev_del = dlb2_pf_cdev_del,
+};
--
2.13.6
next prev parent reply other threads:[~2020-07-12 13:46 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-12 13:43 [PATCH 00/20] dlb2: introduce DLB 2.0 device driver Gage Eads
2020-07-12 13:43 ` [PATCH 01/20] dlb2: add skeleton for DLB 2.0 driver Gage Eads
2020-07-12 15:56 ` Greg KH
2020-07-17 18:19 ` Eads, Gage
2020-07-18 6:46 ` Greg KH
2020-07-12 15:58 ` Greg KH
2020-07-17 18:18 ` Eads, Gage
2020-07-18 6:46 ` Greg KH
2020-07-20 19:02 ` Eads, Gage
2020-07-20 19:19 ` Greg KH
2020-07-24 21:00 ` Eads, Gage
2020-07-12 13:43 ` Gage Eads [this message]
2020-07-12 13:43 ` [PATCH 03/20] dlb2: add resource and device initialization Gage Eads
2020-07-12 13:43 ` [PATCH 04/20] dlb2: add device ioctl layer and first 4 ioctls Gage Eads
2020-07-12 14:42 ` Randy Dunlap
2020-07-17 18:20 ` Eads, Gage
2020-07-12 14:53 ` Randy Dunlap
2020-07-17 18:20 ` Eads, Gage
2020-07-12 15:28 ` Arnd Bergmann
2020-07-17 18:19 ` Eads, Gage
2020-07-17 18:56 ` Arnd Bergmann
2020-07-17 20:05 ` Eads, Gage
2020-07-18 6:48 ` gregkh
2020-08-04 22:20 ` Eads, Gage
2020-08-05 6:46 ` gregkh
2020-08-05 15:07 ` Eads, Gage
2020-08-05 15:17 ` gregkh
2020-08-05 15:39 ` Eads, Gage
2020-07-12 13:43 ` [PATCH 05/20] dlb2: add sched domain config and reset support Gage Eads
2020-07-12 13:43 ` [PATCH 06/20] dlb2: add ioctl to get sched domain fd Gage Eads
2020-07-12 13:43 ` [PATCH 07/20] dlb2: add runtime power-management support Gage Eads
2020-07-12 13:43 ` [PATCH 08/20] dlb2: add queue create and queue-depth-get ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 09/20] dlb2: add ioctl to configure ports, query poll mode Gage Eads
2020-07-12 15:34 ` Arnd Bergmann
2020-07-17 18:19 ` Eads, Gage
2020-07-12 13:43 ` [PATCH 10/20] dlb2: add port mmap support Gage Eads
2020-07-12 13:43 ` [PATCH 11/20] dlb2: add start domain ioctl Gage Eads
2020-07-12 13:43 ` [PATCH 12/20] dlb2: add queue map and unmap ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 13/20] dlb2: add port enable/disable ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 14/20] dlb2: add CQ interrupt support Gage Eads
2020-07-12 13:43 ` [PATCH 15/20] dlb2: add domain alert support Gage Eads
2020-07-12 13:43 ` [PATCH 16/20] dlb2: add sequence-number management ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 17/20] dlb2: add cos bandwidth get/set ioctls Gage Eads
2020-07-12 13:43 ` [PATCH 18/20] dlb2: add device FLR support Gage Eads
2020-07-12 13:43 ` [PATCH 19/20] dlb2: add basic PF sysfs interfaces Gage Eads
2020-07-12 13:43 ` [PATCH 20/20] dlb2: add ingress error handling Gage Eads
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200712134331.8169-3-gage.eads@intel.com \
--to=gage.eads@intel.com \
--cc=arnd@arndb.de \
--cc=bjorn.topel@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=magnus.karlsson@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.