1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2021 Marvell. 3 */ 4 5 #include "roc_api.h" 6 #include "roc_priv.h" 7 8 static int 9 tim_fill_msix(struct roc_tim *roc_tim, uint16_t nb_ring) 10 { 11 struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 12 struct tim *tim = roc_tim_to_tim_priv(roc_tim); 13 struct msix_offset_rsp *rsp; 14 int i, rc; 15 16 mbox_alloc_msg_msix_offset(dev->mbox); 17 rc = mbox_process_msg(dev->mbox, (void **)&rsp); 18 if (rc < 0) 19 return rc; 20 21 for (i = 0; i < nb_ring; i++) 22 tim->tim_msix_offsets[i] = rsp->timlf_msixoff[i]; 23 24 return 0; 25 } 26 27 static void 28 tim_err_desc(int rc) 29 { 30 switch (rc) { 31 case TIM_AF_NO_RINGS_LEFT: 32 plt_err("Unable to allocate new TIM ring."); 33 break; 34 case TIM_AF_INVALID_NPA_PF_FUNC: 35 plt_err("Invalid NPA pf func."); 36 break; 37 case TIM_AF_INVALID_SSO_PF_FUNC: 38 plt_err("Invalid SSO pf func."); 39 break; 40 case TIM_AF_RING_STILL_RUNNING: 41 plt_err("Ring busy."); 42 break; 43 case TIM_AF_LF_INVALID: 44 plt_err("Invalid Ring id."); 45 break; 46 case TIM_AF_CSIZE_NOT_ALIGNED: 47 plt_err("Chunk size specified needs to be multiple of 16."); 48 break; 49 case TIM_AF_CSIZE_TOO_SMALL: 50 plt_err("Chunk size too small."); 51 break; 52 case TIM_AF_CSIZE_TOO_BIG: 53 plt_err("Chunk size too big."); 54 break; 55 case TIM_AF_INTERVAL_TOO_SMALL: 56 plt_err("Bucket traversal interval too small."); 57 break; 58 case TIM_AF_INVALID_BIG_ENDIAN_VALUE: 59 plt_err("Invalid Big endian value."); 60 break; 61 case TIM_AF_INVALID_CLOCK_SOURCE: 62 plt_err("Invalid Clock source specified."); 63 break; 64 case TIM_AF_GPIO_CLK_SRC_NOT_ENABLED: 65 plt_err("GPIO clock source not enabled."); 66 break; 67 case TIM_AF_INVALID_BSIZE: 68 plt_err("Invalid bucket size."); 69 break; 70 case TIM_AF_INVALID_ENABLE_PERIODIC: 71 plt_err("Invalid bucket size."); 72 break; 73 case TIM_AF_INVALID_ENABLE_DONTFREE: 74 plt_err("Invalid Don't free value."); 75 break; 76 case TIM_AF_ENA_DONTFRE_NSET_PERIODIC: 77 plt_err("Don't free bit not set when periodic is enabled."); 78 break; 79 case TIM_AF_RING_ALREADY_DISABLED: 80 plt_err("Ring already stopped"); 81 break; 82 default: 83 plt_err("Unknown Error."); 84 } 85 } 86 87 int 88 roc_tim_lf_enable(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *start_tsc, 89 uint32_t *cur_bkt) 90 { 91 struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 92 struct tim_enable_rsp *rsp; 93 struct tim_ring_req *req; 94 int rc = -ENOSPC; 95 96 req = mbox_alloc_msg_tim_enable_ring(dev->mbox); 97 if (req == NULL) 98 return rc; 99 req->ring = ring_id; 100 101 rc = mbox_process_msg(dev->mbox, (void **)&rsp); 102 if (rc < 0) { 103 tim_err_desc(rc); 104 return rc; 105 } 106 107 if (cur_bkt) 108 *cur_bkt = rsp->currentbucket; 109 if (start_tsc) 110 *start_tsc = rsp->timestarted; 111 112 return 0; 113 } 114 115 int 116 roc_tim_lf_disable(struct roc_tim *roc_tim, uint8_t ring_id) 117 { 118 struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 119 struct tim_ring_req *req; 120 int rc = -ENOSPC; 121 122 req = mbox_alloc_msg_tim_disable_ring(dev->mbox); 123 if (req == NULL) 124 return rc; 125 req->ring = ring_id; 126 127 rc = mbox_process(dev->mbox); 128 if (rc < 0) { 129 tim_err_desc(rc); 130 return rc; 131 } 132 133 return 0; 134 } 135 136 uintptr_t 137 roc_tim_lf_base_get(struct roc_tim *roc_tim, uint8_t ring_id) 138 { 139 struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 140 141 return dev->bar2 + (RVU_BLOCK_ADDR_TIM << 20 | ring_id << 12); 142 } 143 144 int 145 roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id, 146 enum roc_tim_clk_src clk_src, uint8_t ena_periodic, 147 uint8_t ena_dfb, uint32_t bucket_sz, uint32_t chunk_sz, 148 uint32_t interval) 149 { 150 struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 151 struct tim_config_req *req; 152 int rc = -ENOSPC; 153 154 req = mbox_alloc_msg_tim_config_ring(dev->mbox); 155 if (req == NULL) 156 return rc; 157 req->ring = ring_id; 158 req->bigendian = false; 159 req->bucketsize = bucket_sz; 160 req->chunksize = chunk_sz; 161 req->clocksource = clk_src; 162 req->enableperiodic = ena_periodic; 163 req->enabledontfreebuffer = ena_dfb; 164 req->interval = interval; 165 req->gpioedge = TIM_GPIO_LTOH_TRANS; 166 167 rc = mbox_process(dev->mbox); 168 if (rc < 0) { 169 tim_err_desc(rc); 170 return rc; 171 } 172 173 return 0; 174 } 175 176 int 177 roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk) 178 { 179 struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 180 struct tim *tim = roc_tim_to_tim_priv(roc_tim); 181 struct tim_ring_req *free_req; 182 struct tim_lf_alloc_req *req; 183 struct tim_lf_alloc_rsp *rsp; 184 struct dev *dev = &sso->dev; 185 int rc = -ENOSPC; 186 187 req = mbox_alloc_msg_tim_lf_alloc(dev->mbox); 188 if (req == NULL) 189 return rc; 190 req->npa_pf_func = idev_npa_pffunc_get(); 191 req->sso_pf_func = idev_sso_pffunc_get(); 192 req->ring = ring_id; 193 194 rc = mbox_process_msg(dev->mbox, (void **)&rsp); 195 if (rc < 0) { 196 tim_err_desc(rc); 197 return rc; 198 } 199 200 if (clk) 201 *clk = rsp->tenns_clk; 202 203 rc = tim_register_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id, 204 tim->tim_msix_offsets[ring_id]); 205 if (rc < 0) { 206 plt_tim_dbg("Failed to register Ring[%d] IRQ", ring_id); 207 free_req = mbox_alloc_msg_tim_lf_free(dev->mbox); 208 if (free_req == NULL) 209 return -ENOSPC; 210 free_req->ring = ring_id; 211 mbox_process(dev->mbox); 212 } 213 214 return rc; 215 } 216 217 int 218 roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id) 219 { 220 struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 221 struct tim *tim = roc_tim_to_tim_priv(roc_tim); 222 struct dev *dev = &sso->dev; 223 struct tim_ring_req *req; 224 int rc = -ENOSPC; 225 226 tim_unregister_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id, 227 tim->tim_msix_offsets[ring_id]); 228 229 req = mbox_alloc_msg_tim_lf_free(dev->mbox); 230 if (req == NULL) 231 return rc; 232 req->ring = ring_id; 233 234 rc = mbox_process(dev->mbox); 235 if (rc < 0) { 236 tim_err_desc(rc); 237 return rc; 238 } 239 240 return 0; 241 } 242 243 int 244 roc_tim_init(struct roc_tim *roc_tim) 245 { 246 struct rsrc_attach_req *attach_req; 247 struct rsrc_detach_req *detach_req; 248 struct free_rsrcs_rsp *free_rsrc; 249 struct dev *dev; 250 uint16_t nb_lfs; 251 int rc; 252 253 if (roc_tim == NULL || roc_tim->roc_sso == NULL) 254 return TIM_ERR_PARAM; 255 256 PLT_STATIC_ASSERT(sizeof(struct tim) <= TIM_MEM_SZ); 257 dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 258 nb_lfs = roc_tim->nb_lfs; 259 mbox_alloc_msg_free_rsrc_cnt(dev->mbox); 260 rc = mbox_process_msg(dev->mbox, (void *)&free_rsrc); 261 if (rc < 0) { 262 plt_err("Unable to get free rsrc count."); 263 return 0; 264 } 265 266 if (nb_lfs && (free_rsrc->tim < nb_lfs)) { 267 plt_tim_dbg("Requested LFs : %d Available LFs : %d", nb_lfs, 268 free_rsrc->tim); 269 return 0; 270 } 271 272 attach_req = mbox_alloc_msg_attach_resources(dev->mbox); 273 if (attach_req == NULL) 274 return -ENOSPC; 275 attach_req->modify = true; 276 attach_req->timlfs = nb_lfs ? nb_lfs : free_rsrc->tim; 277 nb_lfs = attach_req->timlfs; 278 279 rc = mbox_process(dev->mbox); 280 if (rc < 0) { 281 plt_err("Unable to attach TIM LFs."); 282 return 0; 283 } 284 285 rc = tim_fill_msix(roc_tim, nb_lfs); 286 if (rc < 0) { 287 plt_err("Unable to get TIM MSIX vectors"); 288 289 detach_req = mbox_alloc_msg_detach_resources(dev->mbox); 290 if (detach_req == NULL) 291 return -ENOSPC; 292 detach_req->partial = true; 293 detach_req->timlfs = true; 294 mbox_process(dev->mbox); 295 296 return 0; 297 } 298 299 return nb_lfs; 300 } 301 302 void 303 roc_tim_fini(struct roc_tim *roc_tim) 304 { 305 struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 306 struct rsrc_detach_req *detach_req; 307 308 detach_req = mbox_alloc_msg_detach_resources(dev->mbox); 309 PLT_ASSERT(detach_req); 310 detach_req->partial = true; 311 detach_req->timlfs = true; 312 313 mbox_process(dev->mbox); 314 } 315