event/octeontx: probe ssovf pcie devices

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>
This commit is contained in:
Jerin Jacob 2017-03-03 22:57:47 +05:30
parent 8db0b7de88
commit 00e2be3b62
2 changed files with 110 additions and 0 deletions

View File

@ -34,6 +34,7 @@
#define __SSOVF_EVDEV_H__
#include <rte_config.h>
#include <rte_io.h>
#define EVENTDEV_NAME_OCTEONTX_PMD event_octeontx
@ -54,4 +55,27 @@
RTE_LOG(ERR, EVENTDEV, "[%s] %s() " fmt "\n", \
RTE_STR(EVENTDEV_NAME_OCTEONTX_PMD), __func__, ## args)
#define PCI_VENDOR_ID_CAVIUM 0x177D
#define PCI_DEVICE_ID_OCTEONTX_SSOGRP_VF 0xA04B
#define SSO_MAX_VHGRP (64)
/* SSO VF register offsets */
#define SSO_VHGRP_QCTL (0x010ULL)
#define SSO_VHGRP_INT (0x100ULL)
#define SSO_VHGRP_INT_W1S (0x108ULL)
#define SSO_VHGRP_INT_ENA_W1S (0x110ULL)
#define SSO_VHGRP_INT_ENA_W1C (0x118ULL)
#define SSO_VHGRP_INT_THR (0x140ULL)
#define SSO_VHGRP_INT_CNT (0x180ULL)
#define SSO_VHGRP_XAQ_CNT (0x1B0ULL)
#define SSO_VHGRP_AQ_CNT (0x1C0ULL)
#define SSO_VHGRP_AQ_THR (0x1E0ULL)
#define SSO_VHGRP_PF_MBOX(x) (0x200ULL | ((x) << 3))
/* BAR2 */
#define SSO_VHGRP_OP_ADD_WORK0 (0x00ULL)
#define SSO_VHGRP_OP_ADD_WORK1 (0x08ULL)
#endif /* __SSOVF_EVDEV_H__ */

View File

@ -30,3 +30,89 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <rte_atomic.h>
#include <rte_common.h>
#include <rte_eal.h>
#include <rte_io.h>
#include <rte_pci.h>
#include "ssovf_evdev.h"
struct ssovf_res {
uint16_t domain;
uint16_t vfid;
void *bar0;
void *bar2;
};
struct ssodev {
uint8_t total_ssovfs;
struct ssovf_res grp[SSO_MAX_VHGRP];
};
static struct ssodev sdev;
/* SSOVF pcie device aka event queue probe */
static int
ssovf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
{
uint64_t val;
uint16_t vfid;
uint8_t *idreg;
struct ssovf_res *res;
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) {
ssovf_log_err("Empty bars %p %p",
pci_dev->mem_resource[0].addr,
pci_dev->mem_resource[2].addr);
return -ENODEV;
}
idreg = pci_dev->mem_resource[0].addr;
idreg += SSO_VHGRP_AQ_THR;
val = rte_read64(idreg);
/* Write back the default value of aq_thr */
rte_write64((1ULL << 33) - 1, idreg);
vfid = (val >> 16) & 0xffff;
if (vfid >= SSO_MAX_VHGRP) {
ssovf_log_err("Invalid vfid (%d/%d)", vfid, SSO_MAX_VHGRP);
return -EINVAL;
}
res = &sdev.grp[vfid];
res->vfid = vfid;
res->bar0 = pci_dev->mem_resource[0].addr;
res->bar2 = pci_dev->mem_resource[2].addr;
res->domain = val & 0xffff;
sdev.total_ssovfs++;
rte_wmb();
ssovf_log_dbg("Domain=%d group=%d total_ssovfs=%d", res->domain,
res->vfid, sdev.total_ssovfs);
return 0;
}
static const struct rte_pci_id pci_ssovf_map[] = {
{
RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
PCI_DEVICE_ID_OCTEONTX_SSOGRP_VF)
},
{
.vendor_id = 0,
},
};
static struct rte_pci_driver pci_ssovf = {
.id_table = pci_ssovf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
.probe = ssovf_probe,
};
RTE_PMD_REGISTER_PCI(octeontx_ssovf, pci_ssovf);