1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2021 Marvell. 3 */ 4 #include <fcntl.h> 5 #include <sys/stat.h> 6 #include <sys/types.h> 7 #include <unistd.h> 8 9 #include "roc_api.h" 10 #include "roc_priv.h" 11 12 #define DPI_PF_MBOX_SYSFS_ENTRY "dpi_device_config" 13 14 static inline int 15 send_msg_to_pf(struct plt_pci_addr *pci_addr, const char *value, int size) 16 { 17 char buf[255] = {0}; 18 int res, fd; 19 20 res = snprintf( 21 buf, sizeof(buf), "/sys/bus/pci/devices/" PCI_PRI_FMT "/%s", 22 pci_addr->domain, pci_addr->bus, DPI_PF_DBDF_DEVICE & 0x7, 23 DPI_PF_DBDF_FUNCTION & 0x7, DPI_PF_MBOX_SYSFS_ENTRY); 24 25 if ((res < 0) || ((size_t)res > sizeof(buf))) 26 return -ERANGE; 27 28 fd = open(buf, O_WRONLY); 29 if (fd < 0) 30 return -EACCES; 31 32 res = write(fd, value, size); 33 close(fd); 34 if (res < 0) 35 return -EACCES; 36 37 return 0; 38 } 39 40 int 41 roc_dpi_enable(struct roc_dpi *dpi) 42 { 43 plt_write64(0x1, dpi->rbase + DPI_VDMA_EN); 44 return 0; 45 } 46 47 int 48 roc_dpi_disable(struct roc_dpi *dpi) 49 { 50 plt_write64(0x0, dpi->rbase + DPI_VDMA_EN); 51 return 0; 52 } 53 54 int 55 roc_dpi_configure(struct roc_dpi *roc_dpi) 56 { 57 struct plt_pci_device *pci_dev; 58 const struct plt_memzone *dpi_mz; 59 dpi_mbox_msg_t mbox_msg; 60 struct npa_pool_s pool; 61 struct npa_aura_s aura; 62 int rc, count, buflen; 63 uint64_t aura_handle; 64 plt_iova_t iova; 65 char name[32]; 66 67 if (!roc_dpi) { 68 plt_err("roc_dpi is NULL"); 69 return -EINVAL; 70 } 71 72 pci_dev = roc_dpi->pci_dev; 73 memset(&pool, 0, sizeof(struct npa_pool_s)); 74 pool.nat_align = 1; 75 76 memset(&aura, 0, sizeof(aura)); 77 rc = roc_npa_pool_create(&aura_handle, DPI_CMD_QUEUE_SIZE, 78 DPI_CMD_QUEUE_BUFS, &aura, &pool); 79 if (rc) { 80 plt_err("Failed to create NPA pool, err %d\n", rc); 81 return rc; 82 } 83 84 snprintf(name, sizeof(name), "dpimem%d", roc_dpi->vfid); 85 buflen = DPI_CMD_QUEUE_SIZE * DPI_CMD_QUEUE_BUFS; 86 dpi_mz = plt_memzone_reserve_aligned(name, buflen, 0, 87 DPI_CMD_QUEUE_SIZE); 88 if (dpi_mz == NULL) { 89 plt_err("dpi memzone reserve failed"); 90 rc = -ENOMEM; 91 goto err1; 92 } 93 94 roc_dpi->mz = dpi_mz; 95 iova = dpi_mz->iova; 96 for (count = 0; count < DPI_CMD_QUEUE_BUFS; count++) { 97 roc_npa_aura_op_free(aura_handle, 0, iova); 98 iova += DPI_CMD_QUEUE_SIZE; 99 } 100 101 roc_dpi->chunk_base = (void *)roc_npa_aura_op_alloc(aura_handle, 0); 102 if (!roc_dpi->chunk_base) { 103 plt_err("Failed to alloc buffer from NPA aura"); 104 rc = -ENOMEM; 105 goto err2; 106 } 107 108 roc_dpi->chunk_next = (void *)roc_npa_aura_op_alloc(aura_handle, 0); 109 if (!roc_dpi->chunk_next) { 110 plt_err("Failed to alloc buffer from NPA aura"); 111 rc = -ENOMEM; 112 goto err2; 113 } 114 115 roc_dpi->aura_handle = aura_handle; 116 /* subtract 2 as they have already been alloc'ed above */ 117 roc_dpi->pool_size_m1 = (DPI_CMD_QUEUE_SIZE >> 3) - 2; 118 119 plt_write64(0x0, roc_dpi->rbase + DPI_VDMA_REQQ_CTL); 120 plt_write64(((uint64_t)(roc_dpi->chunk_base) >> 7) << 7, 121 roc_dpi->rbase + DPI_VDMA_SADDR); 122 mbox_msg.u[0] = 0; 123 mbox_msg.u[1] = 0; 124 /* DPI PF driver expects vfid starts from index 0 */ 125 mbox_msg.s.vfid = roc_dpi->vfid; 126 mbox_msg.s.cmd = DPI_QUEUE_OPEN; 127 mbox_msg.s.csize = DPI_CMD_QUEUE_SIZE; 128 mbox_msg.s.aura = roc_npa_aura_handle_to_aura(aura_handle); 129 mbox_msg.s.sso_pf_func = idev_sso_pffunc_get(); 130 mbox_msg.s.npa_pf_func = idev_npa_pffunc_get(); 131 132 rc = send_msg_to_pf(&pci_dev->addr, (const char *)&mbox_msg, 133 sizeof(dpi_mbox_msg_t)); 134 if (rc < 0) { 135 plt_err("Failed to send mbox message %d to DPI PF, err %d", 136 mbox_msg.s.cmd, rc); 137 goto err2; 138 } 139 140 return rc; 141 142 err2: 143 plt_memzone_free(dpi_mz); 144 err1: 145 roc_npa_pool_destroy(aura_handle); 146 return rc; 147 } 148 149 int 150 roc_dpi_dev_init(struct roc_dpi *roc_dpi) 151 { 152 struct plt_pci_device *pci_dev = roc_dpi->pci_dev; 153 uint16_t vfid; 154 155 roc_dpi->rbase = pci_dev->mem_resource[0].addr; 156 vfid = ((pci_dev->addr.devid & 0x1F) << 3) | 157 (pci_dev->addr.function & 0x7); 158 vfid -= 1; 159 roc_dpi->vfid = vfid; 160 plt_spinlock_init(&roc_dpi->chunk_lock); 161 162 return 0; 163 } 164 165 int 166 roc_dpi_dev_fini(struct roc_dpi *roc_dpi) 167 { 168 struct plt_pci_device *pci_dev = roc_dpi->pci_dev; 169 dpi_mbox_msg_t mbox_msg; 170 uint64_t reg; 171 int rc; 172 173 /* Wait for SADDR to become idle */ 174 reg = plt_read64(roc_dpi->rbase + DPI_VDMA_SADDR); 175 while (!(reg & BIT_ULL(63))) 176 reg = plt_read64(roc_dpi->rbase + DPI_VDMA_SADDR); 177 178 mbox_msg.u[0] = 0; 179 mbox_msg.u[1] = 0; 180 mbox_msg.s.vfid = roc_dpi->vfid; 181 mbox_msg.s.cmd = DPI_QUEUE_CLOSE; 182 183 rc = send_msg_to_pf(&pci_dev->addr, (const char *)&mbox_msg, 184 sizeof(dpi_mbox_msg_t)); 185 if (rc < 0) 186 plt_err("Failed to send mbox message %d to DPI PF, err %d", 187 mbox_msg.s.cmd, rc); 188 189 roc_npa_pool_destroy(roc_dpi->aura_handle); 190 plt_memzone_free(roc_dpi->mz); 191 192 return rc; 193 } 194