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