xref: /dpdk/drivers/net/octeontx/base/octeontx_pkovf.c (revision 445371e8ba060ccf482015de9e3b68c934ae8dd8)
1*445371e8SJerin Jacob /*
2*445371e8SJerin Jacob  *   BSD LICENSE
3*445371e8SJerin Jacob  *
4*445371e8SJerin Jacob  *   Copyright (C) Cavium Inc. 2017. All rights reserved.
5*445371e8SJerin Jacob  *
6*445371e8SJerin Jacob  *   Redistribution and use in source and binary forms, with or without
7*445371e8SJerin Jacob  *   modification, are permitted provided that the following conditions
8*445371e8SJerin Jacob  *   are met:
9*445371e8SJerin Jacob  *
10*445371e8SJerin Jacob  *     * Redistributions of source code must retain the above copyright
11*445371e8SJerin Jacob  *       notice, this list of conditions and the following disclaimer.
12*445371e8SJerin Jacob  *     * Redistributions in binary form must reproduce the above copyright
13*445371e8SJerin Jacob  *       notice, this list of conditions and the following disclaimer in
14*445371e8SJerin Jacob  *       the documentation and/or other materials provided with the
15*445371e8SJerin Jacob  *       distribution.
16*445371e8SJerin Jacob  *     * Neither the name of Cavium networks nor the names of its
17*445371e8SJerin Jacob  *       contributors may be used to endorse or promote products derived
18*445371e8SJerin Jacob  *       from this software without specific prior written permission.
19*445371e8SJerin Jacob  *
20*445371e8SJerin Jacob  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*445371e8SJerin Jacob  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*445371e8SJerin Jacob  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23*445371e8SJerin Jacob  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24*445371e8SJerin Jacob  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25*445371e8SJerin Jacob  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26*445371e8SJerin Jacob  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*445371e8SJerin Jacob  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*445371e8SJerin Jacob  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*445371e8SJerin Jacob  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30*445371e8SJerin Jacob  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*445371e8SJerin Jacob  */
32*445371e8SJerin Jacob #include <stdbool.h>
33*445371e8SJerin Jacob #include <string.h>
34*445371e8SJerin Jacob #include <stdio.h>
35*445371e8SJerin Jacob 
36*445371e8SJerin Jacob #include <rte_eal.h>
37*445371e8SJerin Jacob #include <rte_cycles.h>
38*445371e8SJerin Jacob #include <rte_malloc.h>
39*445371e8SJerin Jacob #include <rte_memory.h>
40*445371e8SJerin Jacob #include <rte_pci.h>
41*445371e8SJerin Jacob #include <rte_spinlock.h>
42*445371e8SJerin Jacob 
43*445371e8SJerin Jacob #include "../octeontx_logs.h"
44*445371e8SJerin Jacob #include "octeontx_io.h"
45*445371e8SJerin Jacob #include "octeontx_pkovf.h"
46*445371e8SJerin Jacob 
47*445371e8SJerin Jacob struct octeontx_pko_iomem {
48*445371e8SJerin Jacob 	uint8_t		*va;
49*445371e8SJerin Jacob 	phys_addr_t	iova;
50*445371e8SJerin Jacob 	size_t		size;
51*445371e8SJerin Jacob };
52*445371e8SJerin Jacob 
53*445371e8SJerin Jacob #define PKO_IOMEM_NULL (struct octeontx_pko_iomem){0, 0, 0}
54*445371e8SJerin Jacob 
55*445371e8SJerin Jacob struct octeontx_pko_fc_ctl_s {
56*445371e8SJerin Jacob 	int64_t buf_cnt;
57*445371e8SJerin Jacob 	int64_t padding[(PKO_DQ_FC_STRIDE / 8) - 1];
58*445371e8SJerin Jacob };
59*445371e8SJerin Jacob 
60*445371e8SJerin Jacob struct octeontx_pkovf {
61*445371e8SJerin Jacob 	uint8_t		*bar0;
62*445371e8SJerin Jacob 	uint8_t		*bar2;
63*445371e8SJerin Jacob 	uint16_t	domain;
64*445371e8SJerin Jacob 	uint16_t	vfid;
65*445371e8SJerin Jacob };
66*445371e8SJerin Jacob 
67*445371e8SJerin Jacob struct octeontx_pko_vf_ctl_s {
68*445371e8SJerin Jacob 	rte_spinlock_t lock;
69*445371e8SJerin Jacob 
70*445371e8SJerin Jacob 	struct octeontx_pko_iomem fc_iomem;
71*445371e8SJerin Jacob 	struct octeontx_pko_fc_ctl_s *fc_ctl;
72*445371e8SJerin Jacob 	struct octeontx_pkovf pko[PKO_VF_MAX];
73*445371e8SJerin Jacob 	struct {
74*445371e8SJerin Jacob 		uint64_t chanid;
75*445371e8SJerin Jacob 	} dq_map[PKO_VF_MAX * PKO_VF_NUM_DQ];
76*445371e8SJerin Jacob };
77*445371e8SJerin Jacob 
78*445371e8SJerin Jacob static struct octeontx_pko_vf_ctl_s pko_vf_ctl;
79*445371e8SJerin Jacob 
80*445371e8SJerin Jacob static void
81*445371e8SJerin Jacob octeontx_pkovf_setup(void)
82*445371e8SJerin Jacob {
83*445371e8SJerin Jacob 	static bool init_once;
84*445371e8SJerin Jacob 
85*445371e8SJerin Jacob 	if (!init_once) {
86*445371e8SJerin Jacob 		unsigned int i;
87*445371e8SJerin Jacob 
88*445371e8SJerin Jacob 		rte_spinlock_init(&pko_vf_ctl.lock);
89*445371e8SJerin Jacob 
90*445371e8SJerin Jacob 		pko_vf_ctl.fc_iomem = PKO_IOMEM_NULL;
91*445371e8SJerin Jacob 		pko_vf_ctl.fc_ctl = NULL;
92*445371e8SJerin Jacob 
93*445371e8SJerin Jacob 		for (i = 0; i < PKO_VF_MAX; i++) {
94*445371e8SJerin Jacob 			pko_vf_ctl.pko[i].bar0 = NULL;
95*445371e8SJerin Jacob 			pko_vf_ctl.pko[i].bar2 = NULL;
96*445371e8SJerin Jacob 			pko_vf_ctl.pko[i].domain = ~(uint16_t)0;
97*445371e8SJerin Jacob 			pko_vf_ctl.pko[i].vfid = ~(uint16_t)0;
98*445371e8SJerin Jacob 		}
99*445371e8SJerin Jacob 
100*445371e8SJerin Jacob 		for (i = 0; i < (PKO_VF_MAX * PKO_VF_NUM_DQ); i++)
101*445371e8SJerin Jacob 			pko_vf_ctl.dq_map[i].chanid = 0;
102*445371e8SJerin Jacob 
103*445371e8SJerin Jacob 		init_once = true;
104*445371e8SJerin Jacob 	}
105*445371e8SJerin Jacob }
106*445371e8SJerin Jacob 
107*445371e8SJerin Jacob /* PKOVF pcie device*/
108*445371e8SJerin Jacob static int
109*445371e8SJerin Jacob pkovf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
110*445371e8SJerin Jacob {
111*445371e8SJerin Jacob 	uint64_t val;
112*445371e8SJerin Jacob 	uint16_t vfid;
113*445371e8SJerin Jacob 	uint16_t domain;
114*445371e8SJerin Jacob 	uint8_t *bar0;
115*445371e8SJerin Jacob 	uint8_t *bar2;
116*445371e8SJerin Jacob 	struct octeontx_pkovf *res;
117*445371e8SJerin Jacob 
118*445371e8SJerin Jacob 	RTE_SET_USED(pci_drv);
119*445371e8SJerin Jacob 
120*445371e8SJerin Jacob 	/* For secondary processes, the primary has done all the work */
121*445371e8SJerin Jacob 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
122*445371e8SJerin Jacob 		return 0;
123*445371e8SJerin Jacob 
124*445371e8SJerin Jacob 	if (pci_dev->mem_resource[0].addr == NULL ||
125*445371e8SJerin Jacob 	    pci_dev->mem_resource[2].addr == NULL) {
126*445371e8SJerin Jacob 		octeontx_log_err("Empty bars %p %p",
127*445371e8SJerin Jacob 			pci_dev->mem_resource[0].addr,
128*445371e8SJerin Jacob 			pci_dev->mem_resource[2].addr);
129*445371e8SJerin Jacob 		return -ENODEV;
130*445371e8SJerin Jacob 	}
131*445371e8SJerin Jacob 	bar0 = pci_dev->mem_resource[0].addr;
132*445371e8SJerin Jacob 	bar2 = pci_dev->mem_resource[2].addr;
133*445371e8SJerin Jacob 
134*445371e8SJerin Jacob 	octeontx_pkovf_setup();
135*445371e8SJerin Jacob 
136*445371e8SJerin Jacob 	/* get vfid and domain */
137*445371e8SJerin Jacob 	val = octeontx_read64(bar0 + PKO_VF_DQ_FC_CONFIG);
138*445371e8SJerin Jacob 	domain = (val >> 7) & 0xffff;
139*445371e8SJerin Jacob 	vfid = (val >> 23) & 0xffff;
140*445371e8SJerin Jacob 
141*445371e8SJerin Jacob 	if (unlikely(vfid >= PKO_VF_MAX)) {
142*445371e8SJerin Jacob 		octeontx_log_err("pko: Invalid vfid %d", vfid);
143*445371e8SJerin Jacob 		return -EINVAL;
144*445371e8SJerin Jacob 	}
145*445371e8SJerin Jacob 
146*445371e8SJerin Jacob 	res = &pko_vf_ctl.pko[vfid];
147*445371e8SJerin Jacob 	res->vfid = vfid;
148*445371e8SJerin Jacob 	res->domain = domain;
149*445371e8SJerin Jacob 	res->bar0 = bar0;
150*445371e8SJerin Jacob 	res->bar2 = bar2;
151*445371e8SJerin Jacob 
152*445371e8SJerin Jacob 	octeontx_log_dbg("Domain=%d group=%d", res->domain, res->vfid);
153*445371e8SJerin Jacob 	return 0;
154*445371e8SJerin Jacob }
155*445371e8SJerin Jacob 
156*445371e8SJerin Jacob #define PCI_VENDOR_ID_CAVIUM               0x177D
157*445371e8SJerin Jacob #define PCI_DEVICE_ID_OCTEONTX_PKO_VF      0xA049
158*445371e8SJerin Jacob 
159*445371e8SJerin Jacob static const struct rte_pci_id pci_pkovf_map[] = {
160*445371e8SJerin Jacob 	{
161*445371e8SJerin Jacob 		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
162*445371e8SJerin Jacob 				PCI_DEVICE_ID_OCTEONTX_PKO_VF)
163*445371e8SJerin Jacob 	},
164*445371e8SJerin Jacob 	{
165*445371e8SJerin Jacob 		.vendor_id = 0,
166*445371e8SJerin Jacob 	},
167*445371e8SJerin Jacob };
168*445371e8SJerin Jacob 
169*445371e8SJerin Jacob static struct rte_pci_driver pci_pkovf = {
170*445371e8SJerin Jacob 	.id_table = pci_pkovf_map,
171*445371e8SJerin Jacob 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
172*445371e8SJerin Jacob 	.probe = pkovf_probe,
173*445371e8SJerin Jacob };
174*445371e8SJerin Jacob 
175*445371e8SJerin Jacob RTE_PMD_REGISTER_PCI(octeontx_pkovf, pci_pkovf);
176