event/octeontx: probe ssowvf pcie devices
authorJerin Jacob <jerin.jacob@caviumnetworks.com>
Fri, 3 Mar 2017 17:27:48 +0000 (22:57 +0530)
committerJerin Jacob <jerin.jacob@caviumnetworks.com>
Tue, 4 Apr 2017 17:19:52 +0000 (19:19 +0200)
An event device consists of event queues and event ports.
On Octeontx HW, each event queues(sso group/ssovf) and
event ports(sso hws/ssowvf) are enumerated as separate
SRIOV VF PCIe device. In order to expose as an event device,
On PCIe probe, the driver stores the information associated
with the PCIe device and later with vdev infrastructure
creates event device with earlier probed PCIe VF devices.

Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
Signed-off-by: Santosh Shukla <santosh.shukla@caviumnetworks.com>
Acked-by: Gage Eads <gage.eads@intel.com>
drivers/event/octeontx/ssovf_evdev.h
drivers/event/octeontx/ssovf_probe.c

index 809eed1..0a3c76e 100644 (file)
 
 #define PCI_VENDOR_ID_CAVIUM              0x177D
 #define PCI_DEVICE_ID_OCTEONTX_SSOGRP_VF  0xA04B
+#define PCI_DEVICE_ID_OCTEONTX_SSOWS_VF   0xA04D
 
 #define SSO_MAX_VHGRP                     (64)
+#define SSO_MAX_VHWS                      (32)
 
 /* SSO VF register offsets */
 #define SSO_VHGRP_QCTL                    (0x010ULL)
 #define SSO_VHGRP_OP_ADD_WORK0            (0x00ULL)
 #define SSO_VHGRP_OP_ADD_WORK1            (0x08ULL)
 
+/* SSOW VF register offsets (BAR0) */
+#define SSOW_VHWS_GRPMSK_CHGX(x)          (0x080ULL | ((x) << 3))
+#define SSOW_VHWS_TAG                     (0x300ULL)
+#define SSOW_VHWS_WQP                     (0x308ULL)
+#define SSOW_VHWS_LINKS                   (0x310ULL)
+#define SSOW_VHWS_PENDTAG                 (0x340ULL)
+#define SSOW_VHWS_PENDWQP                 (0x348ULL)
+#define SSOW_VHWS_SWTP                    (0x400ULL)
+#define SSOW_VHWS_OP_ALLOC_WE             (0x410ULL)
+#define SSOW_VHWS_OP_UPD_WQP_GRP0         (0x440ULL)
+#define SSOW_VHWS_OP_UPD_WQP_GRP1         (0x448ULL)
+#define SSOW_VHWS_OP_SWTAG_UNTAG          (0x490ULL)
+#define SSOW_VHWS_OP_SWTAG_CLR            (0x820ULL)
+#define SSOW_VHWS_OP_DESCHED              (0x860ULL)
+#define SSOW_VHWS_OP_DESCHED_NOSCH        (0x870ULL)
+#define SSOW_VHWS_OP_SWTAG_DESCHED        (0x8C0ULL)
+#define SSOW_VHWS_OP_SWTAG_NOSCHED        (0x8D0ULL)
+#define SSOW_VHWS_OP_SWTP_SET             (0xC20ULL)
+#define SSOW_VHWS_OP_SWTAG_NORM           (0xC80ULL)
+#define SSOW_VHWS_OP_SWTAG_FULL0          (0xCA0UL)
+#define SSOW_VHWS_OP_SWTAG_FULL1          (0xCA8ULL)
+#define SSOW_VHWS_OP_CLR_NSCHED           (0x10000ULL)
+#define SSOW_VHWS_OP_GET_WORK0            (0x80000ULL)
+#define SSOW_VHWS_OP_GET_WORK1            (0x80008ULL)
+
+#define SSOW_BAR4_LEN                     (64 * 1024)
 
 #endif /* __SSOVF_EVDEV_H__ */
index 713329c..7033ff5 100644 (file)
@@ -45,12 +45,98 @@ struct ssovf_res {
        void *bar2;
 };
 
+struct ssowvf_res {
+       uint16_t domain;
+       uint16_t vfid;
+       void *bar0;
+       void *bar2;
+       void *bar4;
+};
+
+struct ssowvf_identify {
+       uint16_t domain;
+       uint16_t vfid;
+};
+
 struct ssodev {
        uint8_t total_ssovfs;
+       uint8_t total_ssowvfs;
        struct ssovf_res grp[SSO_MAX_VHGRP];
+       struct ssowvf_res hws[SSO_MAX_VHWS];
 };
+
 static struct ssodev sdev;
 
+/* SSOWVF pcie device aka event port probe */
+
+static int
+ssowvf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
+{
+       uint16_t vfid;
+       struct ssowvf_res *res;
+       struct ssowvf_identify *id;
+
+       RTE_SET_USED(pci_drv);
+
+       /* For secondary processes, the primary has done all the work */
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
+       if (pci_dev->mem_resource[0].addr == NULL ||
+                       pci_dev->mem_resource[2].addr == NULL ||
+                       pci_dev->mem_resource[4].addr == NULL) {
+               ssovf_log_err("Empty bars %p %p %p",
+                               pci_dev->mem_resource[0].addr,
+                               pci_dev->mem_resource[2].addr,
+                               pci_dev->mem_resource[4].addr);
+               return -ENODEV;
+       }
+
+       if (pci_dev->mem_resource[4].len != SSOW_BAR4_LEN) {
+               ssovf_log_err("Bar4 len mismatch %d != %d",
+                       SSOW_BAR4_LEN, (int)pci_dev->mem_resource[4].len);
+               return -EINVAL;
+       }
+
+       id = pci_dev->mem_resource[4].addr;
+       vfid = id->vfid;
+       if (vfid >= SSO_MAX_VHWS) {
+               ssovf_log_err("Invalid vfid(%d/%d)", vfid, SSO_MAX_VHWS);
+               return -EINVAL;
+       }
+
+       res = &sdev.hws[vfid];
+       res->vfid = vfid;
+       res->bar0 = pci_dev->mem_resource[0].addr;
+       res->bar2 = pci_dev->mem_resource[2].addr;
+       res->bar4 = pci_dev->mem_resource[4].addr;
+       res->domain = id->domain;
+
+       sdev.total_ssowvfs++;
+       rte_wmb();
+       ssovf_log_dbg("Domain=%d hws=%d total_ssowvfs=%d", res->domain,
+                       res->vfid, sdev.total_ssowvfs);
+       return 0;
+}
+
+static const struct rte_pci_id pci_ssowvf_map[] = {
+       {
+               RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
+                               PCI_DEVICE_ID_OCTEONTX_SSOWS_VF)
+       },
+       {
+               .vendor_id = 0,
+       },
+};
+
+static struct rte_pci_driver pci_ssowvf = {
+       .id_table = pci_ssowvf_map,
+       .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+       .probe = ssowvf_probe,
+};
+
+RTE_PMD_REGISTER_PCI(octeontx_ssowvf, pci_ssowvf);
+
 /* SSOVF pcie device aka event queue probe */
 
 static int