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