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, uint64_t intervalns, uint64_t clockfreq) 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->intervalns = intervalns; 166 req->clockfreq = clockfreq; 167 req->gpioedge = TIM_GPIO_LTOH_TRANS; 168 169 rc = mbox_process(dev->mbox); 170 if (rc < 0) { 171 tim_err_desc(rc); 172 return rc; 173 } 174 175 return 0; 176 } 177 178 int 179 roc_tim_lf_interval(struct roc_tim *roc_tim, enum roc_tim_clk_src clk_src, 180 uint64_t clockfreq, uint64_t *intervalns, 181 uint64_t *interval) 182 { 183 struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 184 struct tim_intvl_req *req; 185 struct tim_intvl_rsp *rsp; 186 int rc = -ENOSPC; 187 188 req = mbox_alloc_msg_tim_get_min_intvl(dev->mbox); 189 if (req == NULL) 190 return rc; 191 192 req->clockfreq = clockfreq; 193 req->clocksource = clk_src; 194 rc = mbox_process_msg(dev->mbox, (void **)&rsp); 195 if (rc < 0) { 196 tim_err_desc(rc); 197 return rc; 198 } 199 200 *intervalns = rsp->intvl_ns; 201 *interval = rsp->intvl_cyc; 202 203 return 0; 204 } 205 206 int 207 roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk) 208 { 209 struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 210 struct tim *tim = roc_tim_to_tim_priv(roc_tim); 211 struct tim_ring_req *free_req; 212 struct tim_lf_alloc_req *req; 213 struct tim_lf_alloc_rsp *rsp; 214 struct dev *dev = &sso->dev; 215 int rc = -ENOSPC; 216 217 req = mbox_alloc_msg_tim_lf_alloc(dev->mbox); 218 if (req == NULL) 219 return rc; 220 req->npa_pf_func = idev_npa_pffunc_get(); 221 req->sso_pf_func = idev_sso_pffunc_get(); 222 req->ring = ring_id; 223 224 rc = mbox_process_msg(dev->mbox, (void **)&rsp); 225 if (rc < 0) { 226 tim_err_desc(rc); 227 return rc; 228 } 229 230 if (clk) 231 *clk = rsp->tenns_clk; 232 233 rc = tim_register_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id, 234 tim->tim_msix_offsets[ring_id]); 235 if (rc < 0) { 236 plt_tim_dbg("Failed to register Ring[%d] IRQ", ring_id); 237 free_req = mbox_alloc_msg_tim_lf_free(dev->mbox); 238 if (free_req == NULL) 239 return -ENOSPC; 240 free_req->ring = ring_id; 241 mbox_process(dev->mbox); 242 } 243 244 return rc; 245 } 246 247 int 248 roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id) 249 { 250 struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 251 struct tim *tim = roc_tim_to_tim_priv(roc_tim); 252 struct dev *dev = &sso->dev; 253 struct tim_ring_req *req; 254 int rc = -ENOSPC; 255 256 tim_unregister_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id, 257 tim->tim_msix_offsets[ring_id]); 258 259 req = mbox_alloc_msg_tim_lf_free(dev->mbox); 260 if (req == NULL) 261 return rc; 262 req->ring = ring_id; 263 264 rc = mbox_process(dev->mbox); 265 if (rc < 0) { 266 tim_err_desc(rc); 267 return rc; 268 } 269 270 return 0; 271 } 272 273 int 274 roc_tim_init(struct roc_tim *roc_tim) 275 { 276 struct rsrc_attach_req *attach_req; 277 struct rsrc_detach_req *detach_req; 278 struct free_rsrcs_rsp *free_rsrc; 279 struct dev *dev; 280 uint16_t nb_lfs; 281 int rc; 282 283 if (roc_tim == NULL || roc_tim->roc_sso == NULL) 284 return TIM_ERR_PARAM; 285 286 PLT_STATIC_ASSERT(sizeof(struct tim) <= TIM_MEM_SZ); 287 dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 288 nb_lfs = roc_tim->nb_lfs; 289 mbox_alloc_msg_free_rsrc_cnt(dev->mbox); 290 rc = mbox_process_msg(dev->mbox, (void *)&free_rsrc); 291 if (rc < 0) { 292 plt_err("Unable to get free rsrc count."); 293 return 0; 294 } 295 296 if (nb_lfs && (free_rsrc->tim < nb_lfs)) { 297 plt_tim_dbg("Requested LFs : %d Available LFs : %d", nb_lfs, 298 free_rsrc->tim); 299 return 0; 300 } 301 302 attach_req = mbox_alloc_msg_attach_resources(dev->mbox); 303 if (attach_req == NULL) 304 return -ENOSPC; 305 attach_req->modify = true; 306 attach_req->timlfs = nb_lfs ? nb_lfs : free_rsrc->tim; 307 nb_lfs = attach_req->timlfs; 308 309 rc = mbox_process(dev->mbox); 310 if (rc < 0) { 311 plt_err("Unable to attach TIM LFs."); 312 return 0; 313 } 314 315 rc = tim_fill_msix(roc_tim, nb_lfs); 316 if (rc < 0) { 317 plt_err("Unable to get TIM MSIX vectors"); 318 319 detach_req = mbox_alloc_msg_detach_resources(dev->mbox); 320 if (detach_req == NULL) 321 return -ENOSPC; 322 detach_req->partial = true; 323 detach_req->timlfs = true; 324 mbox_process(dev->mbox); 325 326 return 0; 327 } 328 329 return nb_lfs; 330 } 331 332 void 333 roc_tim_fini(struct roc_tim *roc_tim) 334 { 335 struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 336 struct rsrc_detach_req *detach_req; 337 338 detach_req = mbox_alloc_msg_detach_resources(dev->mbox); 339 PLT_ASSERT(detach_req); 340 detach_req->partial = true; 341 detach_req->timlfs = true; 342 343 mbox_process(dev->mbox); 344 } 345