1796e3668SPavan Nikhilesh /* SPDX-License-Identifier: BSD-3-Clause 2796e3668SPavan Nikhilesh * Copyright(C) 2021 Marvell. 3796e3668SPavan Nikhilesh */ 4796e3668SPavan Nikhilesh 5796e3668SPavan Nikhilesh #include "roc_api.h" 6796e3668SPavan Nikhilesh #include "roc_priv.h" 7796e3668SPavan Nikhilesh 8f3c7b607SPavan Nikhilesh #define LF_ENABLE_RETRY_CNT 8 9f3c7b607SPavan Nikhilesh 10309b553cSPavan Nikhilesh static int 11309b553cSPavan Nikhilesh tim_fill_msix(struct roc_tim *roc_tim, uint16_t nb_ring) 12309b553cSPavan Nikhilesh { 13be541d37SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 14309b553cSPavan Nikhilesh struct tim *tim = roc_tim_to_tim_priv(roc_tim); 15be541d37SPavan Nikhilesh struct dev *dev = &sso->dev; 16309b553cSPavan Nikhilesh struct msix_offset_rsp *rsp; 1744a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(dev->mbox); 18309b553cSPavan Nikhilesh int i, rc; 19309b553cSPavan Nikhilesh 2044a9307cSRakesh Kudurumalla mbox_alloc_msg_msix_offset(mbox); 2144a9307cSRakesh Kudurumalla rc = mbox_process_msg(mbox, (void **)&rsp); 2244a9307cSRakesh Kudurumalla if (rc) { 2344a9307cSRakesh Kudurumalla rc = -EIO; 2444a9307cSRakesh Kudurumalla goto exit; 2544a9307cSRakesh Kudurumalla } 26309b553cSPavan Nikhilesh 27309b553cSPavan Nikhilesh for (i = 0; i < nb_ring; i++) 28309b553cSPavan Nikhilesh tim->tim_msix_offsets[i] = rsp->timlf_msixoff[i]; 29309b553cSPavan Nikhilesh 3044a9307cSRakesh Kudurumalla rc = 0; 3144a9307cSRakesh Kudurumalla exit: 3244a9307cSRakesh Kudurumalla mbox_put(mbox); 3344a9307cSRakesh Kudurumalla return rc; 34309b553cSPavan Nikhilesh } 35309b553cSPavan Nikhilesh 36796e3668SPavan Nikhilesh static void 37796e3668SPavan Nikhilesh tim_err_desc(int rc) 38796e3668SPavan Nikhilesh { 39796e3668SPavan Nikhilesh switch (rc) { 40796e3668SPavan Nikhilesh case TIM_AF_NO_RINGS_LEFT: 41796e3668SPavan Nikhilesh plt_err("Unable to allocate new TIM ring."); 42796e3668SPavan Nikhilesh break; 43796e3668SPavan Nikhilesh case TIM_AF_INVALID_NPA_PF_FUNC: 44796e3668SPavan Nikhilesh plt_err("Invalid NPA pf func."); 45796e3668SPavan Nikhilesh break; 46796e3668SPavan Nikhilesh case TIM_AF_INVALID_SSO_PF_FUNC: 47796e3668SPavan Nikhilesh plt_err("Invalid SSO pf func."); 48796e3668SPavan Nikhilesh break; 49796e3668SPavan Nikhilesh case TIM_AF_RING_STILL_RUNNING: 50796e3668SPavan Nikhilesh plt_err("Ring busy."); 51796e3668SPavan Nikhilesh break; 52796e3668SPavan Nikhilesh case TIM_AF_LF_INVALID: 53796e3668SPavan Nikhilesh plt_err("Invalid Ring id."); 54796e3668SPavan Nikhilesh break; 55796e3668SPavan Nikhilesh case TIM_AF_CSIZE_NOT_ALIGNED: 56796e3668SPavan Nikhilesh plt_err("Chunk size specified needs to be multiple of 16."); 57796e3668SPavan Nikhilesh break; 58796e3668SPavan Nikhilesh case TIM_AF_CSIZE_TOO_SMALL: 59796e3668SPavan Nikhilesh plt_err("Chunk size too small."); 60796e3668SPavan Nikhilesh break; 61796e3668SPavan Nikhilesh case TIM_AF_CSIZE_TOO_BIG: 62796e3668SPavan Nikhilesh plt_err("Chunk size too big."); 63796e3668SPavan Nikhilesh break; 64796e3668SPavan Nikhilesh case TIM_AF_INTERVAL_TOO_SMALL: 65796e3668SPavan Nikhilesh plt_err("Bucket traversal interval too small."); 66796e3668SPavan Nikhilesh break; 67796e3668SPavan Nikhilesh case TIM_AF_INVALID_BIG_ENDIAN_VALUE: 68796e3668SPavan Nikhilesh plt_err("Invalid Big endian value."); 69796e3668SPavan Nikhilesh break; 70796e3668SPavan Nikhilesh case TIM_AF_INVALID_CLOCK_SOURCE: 71796e3668SPavan Nikhilesh plt_err("Invalid Clock source specified."); 72796e3668SPavan Nikhilesh break; 73796e3668SPavan Nikhilesh case TIM_AF_GPIO_CLK_SRC_NOT_ENABLED: 74796e3668SPavan Nikhilesh plt_err("GPIO clock source not enabled."); 75796e3668SPavan Nikhilesh break; 76796e3668SPavan Nikhilesh case TIM_AF_INVALID_BSIZE: 77796e3668SPavan Nikhilesh plt_err("Invalid bucket size."); 78796e3668SPavan Nikhilesh break; 79796e3668SPavan Nikhilesh case TIM_AF_INVALID_ENABLE_PERIODIC: 80796e3668SPavan Nikhilesh plt_err("Invalid bucket size."); 81796e3668SPavan Nikhilesh break; 82796e3668SPavan Nikhilesh case TIM_AF_INVALID_ENABLE_DONTFREE: 83796e3668SPavan Nikhilesh plt_err("Invalid Don't free value."); 84796e3668SPavan Nikhilesh break; 85796e3668SPavan Nikhilesh case TIM_AF_ENA_DONTFRE_NSET_PERIODIC: 86796e3668SPavan Nikhilesh plt_err("Don't free bit not set when periodic is enabled."); 87796e3668SPavan Nikhilesh break; 88796e3668SPavan Nikhilesh case TIM_AF_RING_ALREADY_DISABLED: 89796e3668SPavan Nikhilesh plt_err("Ring already stopped"); 90796e3668SPavan Nikhilesh break; 91f3c7b607SPavan Nikhilesh case TIM_AF_LF_START_SYNC_FAIL: 92f3c7b607SPavan Nikhilesh plt_err("Ring start sync failed."); 93f3c7b607SPavan Nikhilesh break; 94796e3668SPavan Nikhilesh default: 95f3c7b607SPavan Nikhilesh plt_err("Unknown Error: %d", rc); 96796e3668SPavan Nikhilesh } 97796e3668SPavan Nikhilesh } 98796e3668SPavan Nikhilesh 99796e3668SPavan Nikhilesh int 10037a94462SPavan Nikhilesh roc_tim_capture_counters(struct roc_tim *roc_tim, uint64_t *counters, uint8_t nb_cntrs) 10137a94462SPavan Nikhilesh { 10237a94462SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 10337a94462SPavan Nikhilesh struct dev *dev = &sso->dev; 10437a94462SPavan Nikhilesh struct mbox *mbox = mbox_get(dev->mbox); 10537a94462SPavan Nikhilesh struct tim_capture_rsp *rsp; 10637a94462SPavan Nikhilesh int rc, i; 10737a94462SPavan Nikhilesh 10837a94462SPavan Nikhilesh mbox_alloc_msg_tim_capture_counters(mbox); 10937a94462SPavan Nikhilesh rc = mbox_process_msg(dev->mbox, (void **)&rsp); 11037a94462SPavan Nikhilesh if (rc) { 11137a94462SPavan Nikhilesh tim_err_desc(rc); 11237a94462SPavan Nikhilesh rc = -EIO; 11337a94462SPavan Nikhilesh goto fail; 11437a94462SPavan Nikhilesh } 11537a94462SPavan Nikhilesh 11637a94462SPavan Nikhilesh for (i = 0; i < nb_cntrs; i++) 11737a94462SPavan Nikhilesh counters[i] = rsp->counters[i]; 11837a94462SPavan Nikhilesh 11937a94462SPavan Nikhilesh fail: 12037a94462SPavan Nikhilesh mbox_put(mbox); 12137a94462SPavan Nikhilesh return rc; 12237a94462SPavan Nikhilesh } 12337a94462SPavan Nikhilesh 12437a94462SPavan Nikhilesh int 125796e3668SPavan Nikhilesh roc_tim_lf_enable(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *start_tsc, 126796e3668SPavan Nikhilesh uint32_t *cur_bkt) 127796e3668SPavan Nikhilesh { 128be541d37SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 129be541d37SPavan Nikhilesh struct dev *dev = &sso->dev; 13044a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(dev->mbox); 131f3c7b607SPavan Nikhilesh uint8_t retry_cnt = LF_ENABLE_RETRY_CNT; 132796e3668SPavan Nikhilesh struct tim_enable_rsp *rsp; 133796e3668SPavan Nikhilesh struct tim_ring_req *req; 134796e3668SPavan Nikhilesh int rc = -ENOSPC; 135796e3668SPavan Nikhilesh 136f3c7b607SPavan Nikhilesh retry: 13744a9307cSRakesh Kudurumalla req = mbox_alloc_msg_tim_enable_ring(mbox); 138796e3668SPavan Nikhilesh if (req == NULL) 139be541d37SPavan Nikhilesh goto fail; 140796e3668SPavan Nikhilesh req->ring = ring_id; 141796e3668SPavan Nikhilesh 142796e3668SPavan Nikhilesh rc = mbox_process_msg(dev->mbox, (void **)&rsp); 143be541d37SPavan Nikhilesh if (rc) { 144f3c7b607SPavan Nikhilesh if (rc == TIM_AF_LF_START_SYNC_FAIL && retry_cnt--) 145f3c7b607SPavan Nikhilesh goto retry; 146f3c7b607SPavan Nikhilesh 147796e3668SPavan Nikhilesh tim_err_desc(rc); 148be541d37SPavan Nikhilesh rc = -EIO; 149be541d37SPavan Nikhilesh goto fail; 150796e3668SPavan Nikhilesh } 151796e3668SPavan Nikhilesh 152796e3668SPavan Nikhilesh if (cur_bkt) 153796e3668SPavan Nikhilesh *cur_bkt = rsp->currentbucket; 154796e3668SPavan Nikhilesh if (start_tsc) 155796e3668SPavan Nikhilesh *start_tsc = rsp->timestarted; 156796e3668SPavan Nikhilesh 157be541d37SPavan Nikhilesh fail: 15844a9307cSRakesh Kudurumalla mbox_put(mbox); 159be541d37SPavan Nikhilesh return rc; 160796e3668SPavan Nikhilesh } 161796e3668SPavan Nikhilesh 162796e3668SPavan Nikhilesh int 163796e3668SPavan Nikhilesh roc_tim_lf_disable(struct roc_tim *roc_tim, uint8_t ring_id) 164796e3668SPavan Nikhilesh { 165be541d37SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 166be541d37SPavan Nikhilesh struct dev *dev = &sso->dev; 16744a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(dev->mbox); 168796e3668SPavan Nikhilesh struct tim_ring_req *req; 169796e3668SPavan Nikhilesh int rc = -ENOSPC; 170796e3668SPavan Nikhilesh 17144a9307cSRakesh Kudurumalla req = mbox_alloc_msg_tim_disable_ring(mbox); 172796e3668SPavan Nikhilesh if (req == NULL) 173be541d37SPavan Nikhilesh goto fail; 174796e3668SPavan Nikhilesh req->ring = ring_id; 175796e3668SPavan Nikhilesh 17637a94462SPavan Nikhilesh rc = mbox_process(mbox); 177be541d37SPavan Nikhilesh if (rc) { 178796e3668SPavan Nikhilesh tim_err_desc(rc); 179be541d37SPavan Nikhilesh rc = -EIO; 180796e3668SPavan Nikhilesh } 181796e3668SPavan Nikhilesh 182be541d37SPavan Nikhilesh fail: 18344a9307cSRakesh Kudurumalla mbox_put(mbox); 184be541d37SPavan Nikhilesh return rc; 185796e3668SPavan Nikhilesh } 186796e3668SPavan Nikhilesh 187796e3668SPavan Nikhilesh uintptr_t 188796e3668SPavan Nikhilesh roc_tim_lf_base_get(struct roc_tim *roc_tim, uint8_t ring_id) 189796e3668SPavan Nikhilesh { 190796e3668SPavan Nikhilesh struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 191796e3668SPavan Nikhilesh 192796e3668SPavan Nikhilesh return dev->bar2 + (RVU_BLOCK_ADDR_TIM << 20 | ring_id << 12); 193796e3668SPavan Nikhilesh } 194796e3668SPavan Nikhilesh 195796e3668SPavan Nikhilesh int 196f3c7b607SPavan Nikhilesh roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id, enum roc_tim_clk_src clk_src, 197f3c7b607SPavan Nikhilesh uint8_t ena_periodic, uint8_t ena_dfb, uint32_t bucket_sz, uint32_t chunk_sz, 198f3c7b607SPavan Nikhilesh uint64_t interval, uint64_t intervalns, uint64_t clockfreq) 199796e3668SPavan Nikhilesh { 200be541d37SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 201be541d37SPavan Nikhilesh struct dev *dev = &sso->dev; 20244a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(dev->mbox); 203796e3668SPavan Nikhilesh struct tim_config_req *req; 204796e3668SPavan Nikhilesh int rc = -ENOSPC; 205796e3668SPavan Nikhilesh 20644a9307cSRakesh Kudurumalla req = mbox_alloc_msg_tim_config_ring(mbox); 207796e3668SPavan Nikhilesh if (req == NULL) 208be541d37SPavan Nikhilesh goto fail; 209796e3668SPavan Nikhilesh req->ring = ring_id; 210796e3668SPavan Nikhilesh req->bigendian = false; 211796e3668SPavan Nikhilesh req->bucketsize = bucket_sz; 212796e3668SPavan Nikhilesh req->chunksize = chunk_sz; 213796e3668SPavan Nikhilesh req->clocksource = clk_src; 214796e3668SPavan Nikhilesh req->enableperiodic = ena_periodic; 215796e3668SPavan Nikhilesh req->enabledontfreebuffer = ena_dfb; 216f3c7b607SPavan Nikhilesh req->interval_lo = interval; 217f3c7b607SPavan Nikhilesh req->interval_hi = interval >> 32; 218dcc97999SPavan Nikhilesh req->intervalns = intervalns; 219dcc97999SPavan Nikhilesh req->clockfreq = clockfreq; 220796e3668SPavan Nikhilesh req->gpioedge = TIM_GPIO_LTOH_TRANS; 221796e3668SPavan Nikhilesh 22244a9307cSRakesh Kudurumalla rc = mbox_process(mbox); 223be541d37SPavan Nikhilesh if (rc) { 224796e3668SPavan Nikhilesh tim_err_desc(rc); 225be541d37SPavan Nikhilesh rc = -EIO; 226796e3668SPavan Nikhilesh } 227796e3668SPavan Nikhilesh 228be541d37SPavan Nikhilesh fail: 22944a9307cSRakesh Kudurumalla mbox_put(mbox); 230be541d37SPavan Nikhilesh return rc; 231796e3668SPavan Nikhilesh } 232796e3668SPavan Nikhilesh 233796e3668SPavan Nikhilesh int 234f3c7b607SPavan Nikhilesh roc_tim_lf_config_hwwqe(struct roc_tim *roc_tim, uint8_t ring_id, struct roc_tim_hwwqe_cfg *cfg) 235f3c7b607SPavan Nikhilesh { 236f3c7b607SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 237f3c7b607SPavan Nikhilesh struct dev *dev = &sso->dev; 238f3c7b607SPavan Nikhilesh struct mbox *mbox = mbox_get(dev->mbox); 239f3c7b607SPavan Nikhilesh struct tim_cfg_hwwqe_req *req; 240f3c7b607SPavan Nikhilesh int rc = -ENOSPC; 241f3c7b607SPavan Nikhilesh 242f3c7b607SPavan Nikhilesh req = mbox_alloc_msg_tim_config_hwwqe(mbox); 243f3c7b607SPavan Nikhilesh if (req == NULL) 244f3c7b607SPavan Nikhilesh goto fail; 245f3c7b607SPavan Nikhilesh req->ring = ring_id; 246f3c7b607SPavan Nikhilesh req->hwwqe_ena = cfg->hwwqe_ena; 247f3c7b607SPavan Nikhilesh req->grp_ena = cfg->grp_ena; 248f3c7b607SPavan Nikhilesh req->grp_tmo_cntr = cfg->grp_tmo_cyc; 249f3c7b607SPavan Nikhilesh req->flw_ctrl_ena = cfg->flw_ctrl_ena; 250f3c7b607SPavan Nikhilesh req->result_offset = cfg->result_offset; 251f3c7b607SPavan Nikhilesh req->event_count_offset = cfg->event_count_offset; 252f3c7b607SPavan Nikhilesh 253f3c7b607SPavan Nikhilesh req->wqe_rd_clr_ena = 1; 254f3c7b607SPavan Nikhilesh req->npa_tmo_cntr = TIM_NPA_TMO; 255f3c7b607SPavan Nikhilesh req->ins_min_gap = TIM_BUCKET_MIN_GAP; 256f3c7b607SPavan Nikhilesh 257f3c7b607SPavan Nikhilesh rc = mbox_process(mbox); 258f3c7b607SPavan Nikhilesh if (rc) { 259f3c7b607SPavan Nikhilesh tim_err_desc(rc); 260f3c7b607SPavan Nikhilesh rc = -EIO; 261f3c7b607SPavan Nikhilesh } 262f3c7b607SPavan Nikhilesh 263f3c7b607SPavan Nikhilesh fail: 264f3c7b607SPavan Nikhilesh mbox_put(mbox); 265f3c7b607SPavan Nikhilesh return rc; 266f3c7b607SPavan Nikhilesh } 267f3c7b607SPavan Nikhilesh 268f3c7b607SPavan Nikhilesh int 269dcc97999SPavan Nikhilesh roc_tim_lf_interval(struct roc_tim *roc_tim, enum roc_tim_clk_src clk_src, 270dcc97999SPavan Nikhilesh uint64_t clockfreq, uint64_t *intervalns, 271dcc97999SPavan Nikhilesh uint64_t *interval) 272dcc97999SPavan Nikhilesh { 273be541d37SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 274be541d37SPavan Nikhilesh struct dev *dev = &sso->dev; 27544a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(dev->mbox); 276dcc97999SPavan Nikhilesh struct tim_intvl_req *req; 277dcc97999SPavan Nikhilesh struct tim_intvl_rsp *rsp; 278dcc97999SPavan Nikhilesh int rc = -ENOSPC; 279dcc97999SPavan Nikhilesh 28044a9307cSRakesh Kudurumalla req = mbox_alloc_msg_tim_get_min_intvl(mbox); 281dcc97999SPavan Nikhilesh if (req == NULL) 282be541d37SPavan Nikhilesh goto fail; 283dcc97999SPavan Nikhilesh 284dcc97999SPavan Nikhilesh req->clockfreq = clockfreq; 285dcc97999SPavan Nikhilesh req->clocksource = clk_src; 286dcc97999SPavan Nikhilesh rc = mbox_process_msg(dev->mbox, (void **)&rsp); 287be541d37SPavan Nikhilesh if (rc) { 288dcc97999SPavan Nikhilesh tim_err_desc(rc); 289be541d37SPavan Nikhilesh rc = -EIO; 290be541d37SPavan Nikhilesh goto fail; 291dcc97999SPavan Nikhilesh } 292dcc97999SPavan Nikhilesh 293dcc97999SPavan Nikhilesh *intervalns = rsp->intvl_ns; 294dcc97999SPavan Nikhilesh *interval = rsp->intvl_cyc; 295dcc97999SPavan Nikhilesh 296be541d37SPavan Nikhilesh fail: 29744a9307cSRakesh Kudurumalla mbox_put(mbox); 298be541d37SPavan Nikhilesh return rc; 299dcc97999SPavan Nikhilesh } 300dcc97999SPavan Nikhilesh 301dcc97999SPavan Nikhilesh int 302796e3668SPavan Nikhilesh roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk) 303796e3668SPavan Nikhilesh { 304796e3668SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 305309b553cSPavan Nikhilesh struct tim *tim = roc_tim_to_tim_priv(roc_tim); 306309b553cSPavan Nikhilesh struct tim_ring_req *free_req; 307796e3668SPavan Nikhilesh struct tim_lf_alloc_req *req; 308796e3668SPavan Nikhilesh struct tim_lf_alloc_rsp *rsp; 309796e3668SPavan Nikhilesh struct dev *dev = &sso->dev; 31044a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(dev->mbox); 311796e3668SPavan Nikhilesh int rc = -ENOSPC; 312796e3668SPavan Nikhilesh 31344a9307cSRakesh Kudurumalla req = mbox_alloc_msg_tim_lf_alloc(mbox); 314796e3668SPavan Nikhilesh if (req == NULL) 315be541d37SPavan Nikhilesh goto fail; 316796e3668SPavan Nikhilesh req->npa_pf_func = idev_npa_pffunc_get(); 317796e3668SPavan Nikhilesh req->sso_pf_func = idev_sso_pffunc_get(); 318796e3668SPavan Nikhilesh req->ring = ring_id; 319796e3668SPavan Nikhilesh 32044a9307cSRakesh Kudurumalla rc = mbox_process_msg(mbox, (void **)&rsp); 321be541d37SPavan Nikhilesh if (rc) { 322796e3668SPavan Nikhilesh tim_err_desc(rc); 323be541d37SPavan Nikhilesh rc = -EIO; 324be541d37SPavan Nikhilesh goto fail; 325796e3668SPavan Nikhilesh } 326796e3668SPavan Nikhilesh 327796e3668SPavan Nikhilesh if (clk) 328796e3668SPavan Nikhilesh *clk = rsp->tenns_clk; 329796e3668SPavan Nikhilesh 330d61138d4SHarman Kalra rc = tim_register_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id, 331309b553cSPavan Nikhilesh tim->tim_msix_offsets[ring_id]); 332309b553cSPavan Nikhilesh if (rc < 0) { 333309b553cSPavan Nikhilesh plt_tim_dbg("Failed to register Ring[%d] IRQ", ring_id); 33444a9307cSRakesh Kudurumalla free_req = mbox_alloc_msg_tim_lf_free(mbox); 335be541d37SPavan Nikhilesh if (free_req == NULL) { 336be541d37SPavan Nikhilesh rc = -ENOSPC; 337be541d37SPavan Nikhilesh goto fail; 338be541d37SPavan Nikhilesh } 339309b553cSPavan Nikhilesh free_req->ring = ring_id; 34044a9307cSRakesh Kudurumalla rc = mbox_process(mbox); 341be541d37SPavan Nikhilesh if (rc) 342be541d37SPavan Nikhilesh rc = -EIO; 343309b553cSPavan Nikhilesh } 344309b553cSPavan Nikhilesh 345be541d37SPavan Nikhilesh fail: 34644a9307cSRakesh Kudurumalla mbox_put(dev->mbox); 347796e3668SPavan Nikhilesh return rc; 348796e3668SPavan Nikhilesh } 349796e3668SPavan Nikhilesh 350796e3668SPavan Nikhilesh int 351796e3668SPavan Nikhilesh roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id) 352796e3668SPavan Nikhilesh { 353796e3668SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 354309b553cSPavan Nikhilesh struct tim *tim = roc_tim_to_tim_priv(roc_tim); 355796e3668SPavan Nikhilesh struct dev *dev = &sso->dev; 356796e3668SPavan Nikhilesh struct tim_ring_req *req; 357796e3668SPavan Nikhilesh int rc = -ENOSPC; 358796e3668SPavan Nikhilesh 359d61138d4SHarman Kalra tim_unregister_irq_priv(roc_tim, sso->pci_dev->intr_handle, ring_id, 360309b553cSPavan Nikhilesh tim->tim_msix_offsets[ring_id]); 361309b553cSPavan Nikhilesh 36244a9307cSRakesh Kudurumalla req = mbox_alloc_msg_tim_lf_free(mbox_get(dev->mbox)); 363796e3668SPavan Nikhilesh if (req == NULL) 364be541d37SPavan Nikhilesh goto fail; 365796e3668SPavan Nikhilesh req->ring = ring_id; 366796e3668SPavan Nikhilesh 367796e3668SPavan Nikhilesh rc = mbox_process(dev->mbox); 368796e3668SPavan Nikhilesh if (rc < 0) { 369796e3668SPavan Nikhilesh tim_err_desc(rc); 370be541d37SPavan Nikhilesh rc = -EIO; 37144a9307cSRakesh Kudurumalla goto fail; 372796e3668SPavan Nikhilesh } 37344a9307cSRakesh Kudurumalla rc = 0; 374796e3668SPavan Nikhilesh 375be541d37SPavan Nikhilesh fail: 37644a9307cSRakesh Kudurumalla mbox_put(dev->mbox); 37744a9307cSRakesh Kudurumalla return rc; 378796e3668SPavan Nikhilesh } 379796e3668SPavan Nikhilesh 380796e3668SPavan Nikhilesh int 381993107f0SShijith Thotton tim_free_lf_count_get(struct dev *dev, uint16_t *nb_lfs) 382993107f0SShijith Thotton { 38344a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(dev->mbox); 384993107f0SShijith Thotton struct free_rsrcs_rsp *rsrc_cnt; 385993107f0SShijith Thotton int rc; 386993107f0SShijith Thotton 38744a9307cSRakesh Kudurumalla mbox_alloc_msg_free_rsrc_cnt(mbox); 38844a9307cSRakesh Kudurumalla rc = mbox_process_msg(mbox, (void **)&rsrc_cnt); 389993107f0SShijith Thotton if (rc) { 390f665790aSDavid Marchand plt_err("Failed to get free resource count"); 39144a9307cSRakesh Kudurumalla mbox_put(mbox); 392993107f0SShijith Thotton return -EIO; 393993107f0SShijith Thotton } 394993107f0SShijith Thotton 395993107f0SShijith Thotton *nb_lfs = rsrc_cnt->tim; 39644a9307cSRakesh Kudurumalla mbox_put(mbox); 397993107f0SShijith Thotton 398993107f0SShijith Thotton return 0; 399993107f0SShijith Thotton } 400993107f0SShijith Thotton 401f3c7b607SPavan Nikhilesh static int 402f3c7b607SPavan Nikhilesh tim_hw_info_get(struct roc_tim *roc_tim) 403f3c7b607SPavan Nikhilesh { 404f3c7b607SPavan Nikhilesh struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev; 405f3c7b607SPavan Nikhilesh struct mbox *mbox = mbox_get(dev->mbox); 406f3c7b607SPavan Nikhilesh struct tim_hw_info *rsp; 407f3c7b607SPavan Nikhilesh int rc; 408f3c7b607SPavan Nikhilesh 409f3c7b607SPavan Nikhilesh mbox_alloc_msg_tim_get_hw_info(mbox); 410f3c7b607SPavan Nikhilesh rc = mbox_process_msg(mbox, (void **)&rsp); 411f3c7b607SPavan Nikhilesh if (rc && rc != MBOX_MSG_INVALID) { 412*822d4ef5SPavan Nikhilesh plt_err("Failed to get TIM HW info"); 413f3c7b607SPavan Nikhilesh rc = -EIO; 414f3c7b607SPavan Nikhilesh goto exit; 415f3c7b607SPavan Nikhilesh } 416f3c7b607SPavan Nikhilesh 417f3c7b607SPavan Nikhilesh if (rc != MBOX_MSG_INVALID) 418f3c7b607SPavan Nikhilesh mbox_memcpy(&roc_tim->feat, &rsp->feat, sizeof(roc_tim->feat)); 419f3c7b607SPavan Nikhilesh 420f3c7b607SPavan Nikhilesh rc = 0; 421f3c7b607SPavan Nikhilesh exit: 422f3c7b607SPavan Nikhilesh mbox_put(mbox); 423f3c7b607SPavan Nikhilesh return rc; 424f3c7b607SPavan Nikhilesh } 425f3c7b607SPavan Nikhilesh 426993107f0SShijith Thotton int 427796e3668SPavan Nikhilesh roc_tim_init(struct roc_tim *roc_tim) 428796e3668SPavan Nikhilesh { 429796e3668SPavan Nikhilesh struct rsrc_attach_req *attach_req; 430309b553cSPavan Nikhilesh struct rsrc_detach_req *detach_req; 431993107f0SShijith Thotton uint16_t nb_lfs, nb_free_lfs; 432be541d37SPavan Nikhilesh struct sso *sso; 433be541d37SPavan Nikhilesh struct dev *dev; 434796e3668SPavan Nikhilesh int rc; 435796e3668SPavan Nikhilesh 436796e3668SPavan Nikhilesh if (roc_tim == NULL || roc_tim->roc_sso == NULL) 437796e3668SPavan Nikhilesh return TIM_ERR_PARAM; 438796e3668SPavan Nikhilesh 439be541d37SPavan Nikhilesh sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 440be541d37SPavan Nikhilesh dev = &sso->dev; 441993107f0SShijith Thotton dev->roc_tim = roc_tim; 442796e3668SPavan Nikhilesh PLT_STATIC_ASSERT(sizeof(struct tim) <= TIM_MEM_SZ); 443796e3668SPavan Nikhilesh nb_lfs = roc_tim->nb_lfs; 444993107f0SShijith Thotton 445f3c7b607SPavan Nikhilesh rc = tim_hw_info_get(roc_tim); 446*822d4ef5SPavan Nikhilesh if (rc) { 447*822d4ef5SPavan Nikhilesh plt_tim_dbg("Failed to get TIM HW info"); 448*822d4ef5SPavan Nikhilesh return 0; 449*822d4ef5SPavan Nikhilesh } 450f3c7b607SPavan Nikhilesh 451993107f0SShijith Thotton rc = tim_free_lf_count_get(dev, &nb_free_lfs); 452be541d37SPavan Nikhilesh if (rc) { 453993107f0SShijith Thotton plt_tim_dbg("Failed to get TIM resource count"); 454be541d37SPavan Nikhilesh nb_lfs = 0; 45544a9307cSRakesh Kudurumalla return nb_lfs; 456796e3668SPavan Nikhilesh } 457796e3668SPavan Nikhilesh 458993107f0SShijith Thotton if (nb_lfs && (nb_free_lfs < nb_lfs)) { 459993107f0SShijith Thotton plt_tim_dbg("Requested LFs : %d Available LFs : %d", nb_lfs, nb_free_lfs); 460be541d37SPavan Nikhilesh nb_lfs = 0; 46144a9307cSRakesh Kudurumalla return nb_lfs; 462796e3668SPavan Nikhilesh } 463796e3668SPavan Nikhilesh 46444a9307cSRakesh Kudurumalla mbox_get(dev->mbox); 465796e3668SPavan Nikhilesh attach_req = mbox_alloc_msg_attach_resources(dev->mbox); 466be541d37SPavan Nikhilesh if (attach_req == NULL) { 467be541d37SPavan Nikhilesh nb_lfs = 0; 468be541d37SPavan Nikhilesh goto fail; 469be541d37SPavan Nikhilesh } 470796e3668SPavan Nikhilesh attach_req->modify = true; 471993107f0SShijith Thotton attach_req->timlfs = nb_lfs ? nb_lfs : nb_free_lfs; 472796e3668SPavan Nikhilesh nb_lfs = attach_req->timlfs; 473796e3668SPavan Nikhilesh 474796e3668SPavan Nikhilesh rc = mbox_process(dev->mbox); 475be541d37SPavan Nikhilesh if (rc) { 476796e3668SPavan Nikhilesh plt_err("Unable to attach TIM LFs."); 477be541d37SPavan Nikhilesh nb_lfs = 0; 478be541d37SPavan Nikhilesh goto fail; 479796e3668SPavan Nikhilesh } 480796e3668SPavan Nikhilesh 48144a9307cSRakesh Kudurumalla mbox_put(dev->mbox); 482309b553cSPavan Nikhilesh rc = tim_fill_msix(roc_tim, nb_lfs); 483309b553cSPavan Nikhilesh if (rc < 0) { 484309b553cSPavan Nikhilesh plt_err("Unable to get TIM MSIX vectors"); 485309b553cSPavan Nikhilesh 48644a9307cSRakesh Kudurumalla detach_req = mbox_alloc_msg_detach_resources(mbox_get(dev->mbox)); 487be541d37SPavan Nikhilesh if (detach_req == NULL) { 488be541d37SPavan Nikhilesh nb_lfs = 0; 489be541d37SPavan Nikhilesh goto fail; 490be541d37SPavan Nikhilesh } 491309b553cSPavan Nikhilesh detach_req->partial = true; 492309b553cSPavan Nikhilesh detach_req->timlfs = true; 493309b553cSPavan Nikhilesh mbox_process(dev->mbox); 494be541d37SPavan Nikhilesh nb_lfs = 0; 49544a9307cSRakesh Kudurumalla } else { 49644a9307cSRakesh Kudurumalla goto done; 497309b553cSPavan Nikhilesh } 498309b553cSPavan Nikhilesh 499be541d37SPavan Nikhilesh fail: 50044a9307cSRakesh Kudurumalla mbox_put(dev->mbox); 50144a9307cSRakesh Kudurumalla done: 5023d668744SShijith Thotton roc_tim->nb_lfs = nb_lfs; 503796e3668SPavan Nikhilesh return nb_lfs; 504796e3668SPavan Nikhilesh } 505796e3668SPavan Nikhilesh 506796e3668SPavan Nikhilesh void 507796e3668SPavan Nikhilesh roc_tim_fini(struct roc_tim *roc_tim) 508796e3668SPavan Nikhilesh { 509be541d37SPavan Nikhilesh struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso); 510796e3668SPavan Nikhilesh struct rsrc_detach_req *detach_req; 511be541d37SPavan Nikhilesh struct dev *dev = &sso->dev; 51244a9307cSRakesh Kudurumalla struct mbox *mbox = mbox_get(dev->mbox); 513796e3668SPavan Nikhilesh 51444a9307cSRakesh Kudurumalla detach_req = mbox_alloc_msg_detach_resources(mbox); 515796e3668SPavan Nikhilesh PLT_ASSERT(detach_req); 516796e3668SPavan Nikhilesh detach_req->partial = true; 517796e3668SPavan Nikhilesh detach_req->timlfs = true; 518796e3668SPavan Nikhilesh 51944a9307cSRakesh Kudurumalla mbox_process(mbox); 52044a9307cSRakesh Kudurumalla mbox_put(mbox); 521796e3668SPavan Nikhilesh } 522