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 inline uint32_t 9 nix_qsize_to_val(enum nix_q_size qsize) 10 { 11 return (16UL << (qsize * 2)); 12 } 13 14 static inline enum nix_q_size 15 nix_qsize_clampup(uint32_t val) 16 { 17 int i = nix_q_size_16; 18 19 for (; i < nix_q_size_max; i++) 20 if (val <= nix_qsize_to_val(i)) 21 break; 22 23 if (i >= nix_q_size_max) 24 i = nix_q_size_max - 1; 25 26 return i; 27 } 28 29 int 30 roc_nix_rq_ena_dis(struct roc_nix_rq *rq, bool enable) 31 { 32 struct nix *nix = roc_nix_to_nix_priv(rq->roc_nix); 33 struct mbox *mbox = (&nix->dev)->mbox; 34 int rc; 35 36 /* Pkts will be dropped silently if RQ is disabled */ 37 if (roc_model_is_cn9k()) { 38 struct nix_aq_enq_req *aq; 39 40 aq = mbox_alloc_msg_nix_aq_enq(mbox); 41 aq->qidx = rq->qid; 42 aq->ctype = NIX_AQ_CTYPE_RQ; 43 aq->op = NIX_AQ_INSTOP_WRITE; 44 45 aq->rq.ena = enable; 46 aq->rq_mask.ena = ~(aq->rq_mask.ena); 47 } else { 48 struct nix_cn10k_aq_enq_req *aq; 49 50 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 51 aq->qidx = rq->qid; 52 aq->ctype = NIX_AQ_CTYPE_RQ; 53 aq->op = NIX_AQ_INSTOP_WRITE; 54 55 aq->rq.ena = enable; 56 aq->rq_mask.ena = ~(aq->rq_mask.ena); 57 } 58 59 rc = mbox_process(mbox); 60 61 if (roc_model_is_cn10k()) 62 plt_write64(rq->qid, nix->base + NIX_LF_OP_VWQE_FLUSH); 63 return rc; 64 } 65 66 static int 67 rq_cn9k_cfg(struct nix *nix, struct roc_nix_rq *rq, bool cfg, bool ena) 68 { 69 struct mbox *mbox = (&nix->dev)->mbox; 70 struct nix_aq_enq_req *aq; 71 72 aq = mbox_alloc_msg_nix_aq_enq(mbox); 73 aq->qidx = rq->qid; 74 aq->ctype = NIX_AQ_CTYPE_RQ; 75 aq->op = cfg ? NIX_AQ_INSTOP_WRITE : NIX_AQ_INSTOP_INIT; 76 77 if (rq->sso_ena) { 78 /* SSO mode */ 79 aq->rq.sso_ena = 1; 80 aq->rq.sso_tt = rq->tt; 81 aq->rq.sso_grp = rq->hwgrp; 82 aq->rq.ena_wqwd = 1; 83 aq->rq.wqe_skip = rq->wqe_skip; 84 aq->rq.wqe_caching = 1; 85 86 aq->rq.good_utag = rq->tag_mask >> 24; 87 aq->rq.bad_utag = rq->tag_mask >> 24; 88 aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0); 89 } else { 90 /* CQ mode */ 91 aq->rq.sso_ena = 0; 92 aq->rq.good_utag = rq->tag_mask >> 24; 93 aq->rq.bad_utag = rq->tag_mask >> 24; 94 aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0); 95 aq->rq.cq = rq->qid; 96 } 97 98 if (rq->ipsech_ena) 99 aq->rq.ipsech_ena = 1; 100 101 aq->rq.spb_ena = 0; 102 aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle); 103 104 /* Sizes must be aligned to 8 bytes */ 105 if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7) 106 return -EINVAL; 107 108 /* Expressed in number of dwords */ 109 aq->rq.first_skip = rq->first_skip / 8; 110 aq->rq.later_skip = rq->later_skip / 8; 111 aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */ 112 aq->rq.lpb_sizem1 = rq->lpb_size / 8; 113 aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */ 114 aq->rq.ena = ena; 115 aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */ 116 aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */ 117 aq->rq.rq_int_ena = 0; 118 /* Many to one reduction */ 119 aq->rq.qint_idx = rq->qid % nix->qints; 120 aq->rq.xqe_drop_ena = 1; 121 122 /* If RED enabled, then fill enable for all cases */ 123 if (rq->red_pass && (rq->red_pass >= rq->red_drop)) { 124 aq->rq.spb_aura_pass = rq->spb_red_pass; 125 aq->rq.lpb_aura_pass = rq->red_pass; 126 127 aq->rq.spb_aura_drop = rq->spb_red_drop; 128 aq->rq.lpb_aura_drop = rq->red_drop; 129 } 130 131 if (cfg) { 132 if (rq->sso_ena) { 133 /* SSO mode */ 134 aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena; 135 aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt; 136 aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp; 137 aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd; 138 aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip; 139 aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching; 140 aq->rq_mask.good_utag = ~aq->rq_mask.good_utag; 141 aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag; 142 aq->rq_mask.ltag = ~aq->rq_mask.ltag; 143 } else { 144 /* CQ mode */ 145 aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena; 146 aq->rq_mask.good_utag = ~aq->rq_mask.good_utag; 147 aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag; 148 aq->rq_mask.ltag = ~aq->rq_mask.ltag; 149 aq->rq_mask.cq = ~aq->rq_mask.cq; 150 } 151 152 if (rq->ipsech_ena) 153 aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena; 154 155 aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena; 156 aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura; 157 aq->rq_mask.first_skip = ~aq->rq_mask.first_skip; 158 aq->rq_mask.later_skip = ~aq->rq_mask.later_skip; 159 aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw; 160 aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1; 161 aq->rq_mask.ena = ~aq->rq_mask.ena; 162 aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching; 163 aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size; 164 aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena; 165 aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx; 166 aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena; 167 168 if (rq->red_pass && (rq->red_pass >= rq->red_drop)) { 169 aq->rq_mask.spb_aura_pass = ~aq->rq_mask.spb_aura_pass; 170 aq->rq_mask.lpb_aura_pass = ~aq->rq_mask.lpb_aura_pass; 171 172 aq->rq_mask.spb_aura_drop = ~aq->rq_mask.spb_aura_drop; 173 aq->rq_mask.lpb_aura_drop = ~aq->rq_mask.lpb_aura_drop; 174 } 175 } 176 177 return 0; 178 } 179 180 static int 181 rq_cfg(struct nix *nix, struct roc_nix_rq *rq, bool cfg, bool ena) 182 { 183 struct mbox *mbox = (&nix->dev)->mbox; 184 struct nix_cn10k_aq_enq_req *aq; 185 186 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 187 aq->qidx = rq->qid; 188 aq->ctype = NIX_AQ_CTYPE_RQ; 189 aq->op = cfg ? NIX_AQ_INSTOP_WRITE : NIX_AQ_INSTOP_INIT; 190 191 if (rq->sso_ena) { 192 /* SSO mode */ 193 aq->rq.sso_ena = 1; 194 aq->rq.sso_tt = rq->tt; 195 aq->rq.sso_grp = rq->hwgrp; 196 aq->rq.ena_wqwd = 1; 197 aq->rq.wqe_skip = rq->wqe_skip; 198 aq->rq.wqe_caching = 1; 199 200 aq->rq.good_utag = rq->tag_mask >> 24; 201 aq->rq.bad_utag = rq->tag_mask >> 24; 202 aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0); 203 204 if (rq->vwqe_ena) { 205 aq->rq.vwqe_ena = true; 206 aq->rq.vwqe_skip = rq->vwqe_first_skip; 207 /* Maximal Vector size is (2^(MAX_VSIZE_EXP+2)) */ 208 aq->rq.max_vsize_exp = rq->vwqe_max_sz_exp - 2; 209 aq->rq.vtime_wait = rq->vwqe_wait_tmo; 210 aq->rq.wqe_aura = rq->vwqe_aura_handle; 211 } 212 } else { 213 /* CQ mode */ 214 aq->rq.sso_ena = 0; 215 aq->rq.good_utag = rq->tag_mask >> 24; 216 aq->rq.bad_utag = rq->tag_mask >> 24; 217 aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0); 218 aq->rq.cq = rq->qid; 219 } 220 221 if (rq->ipsech_ena) 222 aq->rq.ipsech_ena = 1; 223 224 aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle); 225 226 /* Sizes must be aligned to 8 bytes */ 227 if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7) 228 return -EINVAL; 229 230 /* Expressed in number of dwords */ 231 aq->rq.first_skip = rq->first_skip / 8; 232 aq->rq.later_skip = rq->later_skip / 8; 233 aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */ 234 aq->rq.lpb_sizem1 = rq->lpb_size / 8; 235 aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */ 236 aq->rq.ena = ena; 237 238 if (rq->spb_ena) { 239 uint32_t spb_sizem1; 240 241 aq->rq.spb_ena = 1; 242 aq->rq.spb_aura = 243 roc_npa_aura_handle_to_aura(rq->spb_aura_handle); 244 245 if (rq->spb_size & 0x7 || 246 rq->spb_size > NIX_RQ_CN10K_SPB_MAX_SIZE) 247 return -EINVAL; 248 249 spb_sizem1 = rq->spb_size / 8; /* Expressed in no. of dwords */ 250 spb_sizem1 -= 1; /* Expressed in size minus one */ 251 aq->rq.spb_sizem1 = spb_sizem1 & 0x3F; 252 aq->rq.spb_high_sizem1 = (spb_sizem1 >> 6) & 0x7; 253 } else { 254 aq->rq.spb_ena = 0; 255 } 256 257 aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */ 258 aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */ 259 aq->rq.rq_int_ena = 0; 260 /* Many to one reduction */ 261 aq->rq.qint_idx = rq->qid % nix->qints; 262 aq->rq.xqe_drop_ena = 1; 263 264 /* If RED enabled, then fill enable for all cases */ 265 if (rq->red_pass && (rq->red_pass >= rq->red_drop)) { 266 aq->rq.spb_pool_pass = rq->red_pass; 267 aq->rq.spb_aura_pass = rq->red_pass; 268 aq->rq.lpb_pool_pass = rq->red_pass; 269 aq->rq.lpb_aura_pass = rq->red_pass; 270 aq->rq.wqe_pool_pass = rq->red_pass; 271 aq->rq.xqe_pass = rq->red_pass; 272 273 aq->rq.spb_pool_drop = rq->red_drop; 274 aq->rq.spb_aura_drop = rq->red_drop; 275 aq->rq.lpb_pool_drop = rq->red_drop; 276 aq->rq.lpb_aura_drop = rq->red_drop; 277 aq->rq.wqe_pool_drop = rq->red_drop; 278 aq->rq.xqe_drop = rq->red_drop; 279 } 280 281 if (cfg) { 282 if (rq->sso_ena) { 283 /* SSO mode */ 284 aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena; 285 aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt; 286 aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp; 287 aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd; 288 aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip; 289 aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching; 290 aq->rq_mask.good_utag = ~aq->rq_mask.good_utag; 291 aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag; 292 aq->rq_mask.ltag = ~aq->rq_mask.ltag; 293 if (rq->vwqe_ena) { 294 aq->rq_mask.vwqe_ena = ~aq->rq_mask.vwqe_ena; 295 aq->rq_mask.vwqe_skip = ~aq->rq_mask.vwqe_skip; 296 aq->rq_mask.max_vsize_exp = 297 ~aq->rq_mask.max_vsize_exp; 298 aq->rq_mask.vtime_wait = 299 ~aq->rq_mask.vtime_wait; 300 aq->rq_mask.wqe_aura = ~aq->rq_mask.wqe_aura; 301 } 302 } else { 303 /* CQ mode */ 304 aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena; 305 aq->rq_mask.good_utag = ~aq->rq_mask.good_utag; 306 aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag; 307 aq->rq_mask.ltag = ~aq->rq_mask.ltag; 308 aq->rq_mask.cq = ~aq->rq_mask.cq; 309 } 310 311 if (rq->ipsech_ena) 312 aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena; 313 314 if (rq->spb_ena) { 315 aq->rq_mask.spb_aura = ~aq->rq_mask.spb_aura; 316 aq->rq_mask.spb_sizem1 = ~aq->rq_mask.spb_sizem1; 317 aq->rq_mask.spb_high_sizem1 = 318 ~aq->rq_mask.spb_high_sizem1; 319 } 320 321 aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena; 322 aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura; 323 aq->rq_mask.first_skip = ~aq->rq_mask.first_skip; 324 aq->rq_mask.later_skip = ~aq->rq_mask.later_skip; 325 aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw; 326 aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1; 327 aq->rq_mask.ena = ~aq->rq_mask.ena; 328 aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching; 329 aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size; 330 aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena; 331 aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx; 332 aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena; 333 334 if (rq->red_pass && (rq->red_pass >= rq->red_drop)) { 335 aq->rq_mask.spb_pool_pass = ~aq->rq_mask.spb_pool_pass; 336 aq->rq_mask.spb_aura_pass = ~aq->rq_mask.spb_aura_pass; 337 aq->rq_mask.lpb_pool_pass = ~aq->rq_mask.lpb_pool_pass; 338 aq->rq_mask.lpb_aura_pass = ~aq->rq_mask.lpb_aura_pass; 339 aq->rq_mask.wqe_pool_pass = ~aq->rq_mask.wqe_pool_pass; 340 aq->rq_mask.xqe_pass = ~aq->rq_mask.xqe_pass; 341 342 aq->rq_mask.spb_pool_drop = ~aq->rq_mask.spb_pool_drop; 343 aq->rq_mask.spb_aura_drop = ~aq->rq_mask.spb_aura_drop; 344 aq->rq_mask.lpb_pool_drop = ~aq->rq_mask.lpb_pool_drop; 345 aq->rq_mask.lpb_aura_drop = ~aq->rq_mask.lpb_aura_drop; 346 aq->rq_mask.wqe_pool_drop = ~aq->rq_mask.wqe_pool_drop; 347 aq->rq_mask.xqe_drop = ~aq->rq_mask.xqe_drop; 348 } 349 } 350 351 return 0; 352 } 353 354 int 355 roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena) 356 { 357 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 358 struct mbox *mbox = (&nix->dev)->mbox; 359 bool is_cn9k = roc_model_is_cn9k(); 360 int rc; 361 362 if (roc_nix == NULL || rq == NULL) 363 return NIX_ERR_PARAM; 364 365 if (rq->qid >= nix->nb_rx_queues) 366 return NIX_ERR_QUEUE_INVALID_RANGE; 367 368 rq->roc_nix = roc_nix; 369 370 if (is_cn9k) 371 rc = rq_cn9k_cfg(nix, rq, false, ena); 372 else 373 rc = rq_cfg(nix, rq, false, ena); 374 375 if (rc) 376 return rc; 377 378 return mbox_process(mbox); 379 } 380 381 int 382 roc_nix_rq_modify(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena) 383 { 384 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 385 struct mbox *mbox = (&nix->dev)->mbox; 386 bool is_cn9k = roc_model_is_cn9k(); 387 int rc; 388 389 if (roc_nix == NULL || rq == NULL) 390 return NIX_ERR_PARAM; 391 392 if (rq->qid >= nix->nb_rx_queues) 393 return NIX_ERR_QUEUE_INVALID_RANGE; 394 395 rq->roc_nix = roc_nix; 396 397 if (is_cn9k) 398 rc = rq_cn9k_cfg(nix, rq, true, ena); 399 else 400 rc = rq_cfg(nix, rq, true, ena); 401 402 if (rc) 403 return rc; 404 405 return mbox_process(mbox); 406 } 407 408 int 409 roc_nix_rq_fini(struct roc_nix_rq *rq) 410 { 411 /* Disabling RQ is sufficient */ 412 return roc_nix_rq_ena_dis(rq, false); 413 } 414 415 int 416 roc_nix_cq_init(struct roc_nix *roc_nix, struct roc_nix_cq *cq) 417 { 418 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 419 struct mbox *mbox = (&nix->dev)->mbox; 420 volatile struct nix_cq_ctx_s *cq_ctx; 421 enum nix_q_size qsize; 422 size_t desc_sz; 423 int rc; 424 425 if (cq == NULL) 426 return NIX_ERR_PARAM; 427 428 if (cq->qid >= nix->nb_rx_queues) 429 return NIX_ERR_QUEUE_INVALID_RANGE; 430 431 qsize = nix_qsize_clampup(cq->nb_desc); 432 cq->nb_desc = nix_qsize_to_val(qsize); 433 cq->qmask = cq->nb_desc - 1; 434 cq->door = nix->base + NIX_LF_CQ_OP_DOOR; 435 cq->status = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS); 436 cq->wdata = (uint64_t)cq->qid << 32; 437 cq->roc_nix = roc_nix; 438 cq->drop_thresh = NIX_CQ_THRESH_LEVEL; 439 440 /* CQE of W16 */ 441 desc_sz = cq->nb_desc * NIX_CQ_ENTRY_SZ; 442 cq->desc_base = plt_zmalloc(desc_sz, NIX_CQ_ALIGN); 443 if (cq->desc_base == NULL) { 444 rc = NIX_ERR_NO_MEM; 445 goto fail; 446 } 447 448 if (roc_model_is_cn9k()) { 449 struct nix_aq_enq_req *aq; 450 451 aq = mbox_alloc_msg_nix_aq_enq(mbox); 452 aq->qidx = cq->qid; 453 aq->ctype = NIX_AQ_CTYPE_CQ; 454 aq->op = NIX_AQ_INSTOP_INIT; 455 cq_ctx = &aq->cq; 456 } else { 457 struct nix_cn10k_aq_enq_req *aq; 458 459 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 460 aq->qidx = cq->qid; 461 aq->ctype = NIX_AQ_CTYPE_CQ; 462 aq->op = NIX_AQ_INSTOP_INIT; 463 cq_ctx = &aq->cq; 464 } 465 466 cq_ctx->ena = 1; 467 cq_ctx->caching = 1; 468 cq_ctx->qsize = qsize; 469 cq_ctx->base = (uint64_t)cq->desc_base; 470 cq_ctx->avg_level = 0xff; 471 cq_ctx->cq_err_int_ena = BIT(NIX_CQERRINT_CQE_FAULT); 472 cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_DOOR_ERR); 473 474 /* Many to one reduction */ 475 cq_ctx->qint_idx = cq->qid % nix->qints; 476 /* Map CQ0 [RQ0] to CINT0 and so on till max 64 irqs */ 477 cq_ctx->cint_idx = cq->qid; 478 479 cq_ctx->drop = cq->drop_thresh; 480 cq_ctx->drop_ena = 1; 481 482 /* TX pause frames enable flow ctrl on RX side */ 483 if (nix->tx_pause) { 484 /* Single BPID is allocated for all rx channels for now */ 485 cq_ctx->bpid = nix->bpid[0]; 486 cq_ctx->bp = cq_ctx->drop; 487 cq_ctx->bp_ena = 1; 488 } 489 490 rc = mbox_process(mbox); 491 if (rc) 492 goto free_mem; 493 494 return 0; 495 496 free_mem: 497 plt_free(cq->desc_base); 498 fail: 499 return rc; 500 } 501 502 int 503 roc_nix_cq_fini(struct roc_nix_cq *cq) 504 { 505 struct mbox *mbox; 506 struct nix *nix; 507 int rc; 508 509 if (cq == NULL) 510 return NIX_ERR_PARAM; 511 512 nix = roc_nix_to_nix_priv(cq->roc_nix); 513 mbox = (&nix->dev)->mbox; 514 515 /* Disable CQ */ 516 if (roc_model_is_cn9k()) { 517 struct nix_aq_enq_req *aq; 518 519 aq = mbox_alloc_msg_nix_aq_enq(mbox); 520 aq->qidx = cq->qid; 521 aq->ctype = NIX_AQ_CTYPE_CQ; 522 aq->op = NIX_AQ_INSTOP_WRITE; 523 aq->cq.ena = 0; 524 aq->cq.bp_ena = 0; 525 aq->cq_mask.ena = ~aq->cq_mask.ena; 526 aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena; 527 } else { 528 struct nix_cn10k_aq_enq_req *aq; 529 530 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 531 aq->qidx = cq->qid; 532 aq->ctype = NIX_AQ_CTYPE_CQ; 533 aq->op = NIX_AQ_INSTOP_WRITE; 534 aq->cq.ena = 0; 535 aq->cq.bp_ena = 0; 536 aq->cq_mask.ena = ~aq->cq_mask.ena; 537 aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena; 538 } 539 540 rc = mbox_process(mbox); 541 if (rc) 542 return rc; 543 544 plt_free(cq->desc_base); 545 return 0; 546 } 547 548 static int 549 sqb_pool_populate(struct roc_nix *roc_nix, struct roc_nix_sq *sq) 550 { 551 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 552 uint16_t sqes_per_sqb, count, nb_sqb_bufs; 553 struct npa_pool_s pool; 554 struct npa_aura_s aura; 555 uint64_t blk_sz; 556 uint64_t iova; 557 int rc; 558 559 blk_sz = nix->sqb_size; 560 if (sq->max_sqe_sz == roc_nix_maxsqesz_w16) 561 sqes_per_sqb = (blk_sz / 8) / 16; 562 else 563 sqes_per_sqb = (blk_sz / 8) / 8; 564 565 sq->nb_desc = PLT_MAX(256U, sq->nb_desc); 566 nb_sqb_bufs = sq->nb_desc / sqes_per_sqb; 567 nb_sqb_bufs += NIX_SQB_LIST_SPACE; 568 /* Clamp up the SQB count */ 569 nb_sqb_bufs = PLT_MIN(roc_nix->max_sqb_count, 570 (uint16_t)PLT_MAX(NIX_DEF_SQB, nb_sqb_bufs)); 571 572 sq->nb_sqb_bufs = nb_sqb_bufs; 573 sq->sqes_per_sqb_log2 = (uint16_t)plt_log2_u32(sqes_per_sqb); 574 sq->nb_sqb_bufs_adj = 575 nb_sqb_bufs - 576 (PLT_ALIGN_MUL_CEIL(nb_sqb_bufs, sqes_per_sqb) / sqes_per_sqb); 577 sq->nb_sqb_bufs_adj = 578 (sq->nb_sqb_bufs_adj * NIX_SQB_LOWER_THRESH) / 100; 579 580 /* Explicitly set nat_align alone as by default pool is with both 581 * nat_align and buf_offset = 1 which we don't want for SQB. 582 */ 583 memset(&pool, 0, sizeof(struct npa_pool_s)); 584 pool.nat_align = 1; 585 586 memset(&aura, 0, sizeof(aura)); 587 aura.fc_ena = 1; 588 if (roc_model_is_cn9k() || roc_model_is_cn10ka_a0()) 589 aura.fc_stype = 0x0; /* STF */ 590 else 591 aura.fc_stype = 0x3; /* STSTP */ 592 aura.fc_addr = (uint64_t)sq->fc; 593 aura.fc_hyst_bits = 0; /* Store count on all updates */ 594 rc = roc_npa_pool_create(&sq->aura_handle, blk_sz, NIX_MAX_SQB, &aura, 595 &pool); 596 if (rc) 597 goto fail; 598 599 sq->sqe_mem = plt_zmalloc(blk_sz * NIX_MAX_SQB, blk_sz); 600 if (sq->sqe_mem == NULL) { 601 rc = NIX_ERR_NO_MEM; 602 goto nomem; 603 } 604 605 /* Fill the initial buffers */ 606 iova = (uint64_t)sq->sqe_mem; 607 for (count = 0; count < NIX_MAX_SQB; count++) { 608 roc_npa_aura_op_free(sq->aura_handle, 0, iova); 609 iova += blk_sz; 610 } 611 roc_npa_aura_op_range_set(sq->aura_handle, (uint64_t)sq->sqe_mem, iova); 612 roc_npa_aura_limit_modify(sq->aura_handle, sq->nb_sqb_bufs); 613 sq->aura_sqb_bufs = NIX_MAX_SQB; 614 615 return rc; 616 nomem: 617 roc_npa_pool_destroy(sq->aura_handle); 618 fail: 619 return rc; 620 } 621 622 static void 623 sq_cn9k_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, 624 uint16_t smq) 625 { 626 struct mbox *mbox = (&nix->dev)->mbox; 627 struct nix_aq_enq_req *aq; 628 629 aq = mbox_alloc_msg_nix_aq_enq(mbox); 630 aq->qidx = sq->qid; 631 aq->ctype = NIX_AQ_CTYPE_SQ; 632 aq->op = NIX_AQ_INSTOP_INIT; 633 aq->sq.max_sqe_size = sq->max_sqe_sz; 634 635 aq->sq.max_sqe_size = sq->max_sqe_sz; 636 aq->sq.smq = smq; 637 aq->sq.smq_rr_quantum = rr_quantum; 638 aq->sq.default_chan = nix->tx_chan_base; 639 aq->sq.sqe_stype = NIX_STYPE_STF; 640 aq->sq.ena = 1; 641 aq->sq.sso_ena = !!sq->sso_ena; 642 if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8) 643 aq->sq.sqe_stype = NIX_STYPE_STP; 644 aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle); 645 aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR); 646 aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL); 647 aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR); 648 aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR); 649 650 /* Many to one reduction */ 651 aq->sq.qint_idx = sq->qid % nix->qints; 652 } 653 654 static int 655 sq_cn9k_fini(struct nix *nix, struct roc_nix_sq *sq) 656 { 657 struct mbox *mbox = (&nix->dev)->mbox; 658 struct nix_aq_enq_rsp *rsp; 659 struct nix_aq_enq_req *aq; 660 uint16_t sqes_per_sqb; 661 void *sqb_buf; 662 int rc, count; 663 664 aq = mbox_alloc_msg_nix_aq_enq(mbox); 665 aq->qidx = sq->qid; 666 aq->ctype = NIX_AQ_CTYPE_SQ; 667 aq->op = NIX_AQ_INSTOP_READ; 668 rc = mbox_process_msg(mbox, (void *)&rsp); 669 if (rc) 670 return rc; 671 672 /* Check if sq is already cleaned up */ 673 if (!rsp->sq.ena) 674 return 0; 675 676 /* Disable sq */ 677 aq = mbox_alloc_msg_nix_aq_enq(mbox); 678 aq->qidx = sq->qid; 679 aq->ctype = NIX_AQ_CTYPE_SQ; 680 aq->op = NIX_AQ_INSTOP_WRITE; 681 aq->sq_mask.ena = ~aq->sq_mask.ena; 682 aq->sq.ena = 0; 683 rc = mbox_process(mbox); 684 if (rc) 685 return rc; 686 687 /* Read SQ and free sqb's */ 688 aq = mbox_alloc_msg_nix_aq_enq(mbox); 689 aq->qidx = sq->qid; 690 aq->ctype = NIX_AQ_CTYPE_SQ; 691 aq->op = NIX_AQ_INSTOP_READ; 692 rc = mbox_process_msg(mbox, (void *)&rsp); 693 if (rc) 694 return rc; 695 696 if (aq->sq.smq_pend) 697 plt_err("SQ has pending SQE's"); 698 699 count = aq->sq.sqb_count; 700 sqes_per_sqb = 1 << sq->sqes_per_sqb_log2; 701 /* Free SQB's that are used */ 702 sqb_buf = (void *)rsp->sq.head_sqb; 703 while (count) { 704 void *next_sqb; 705 706 next_sqb = *(void **)((uintptr_t)sqb_buf + 707 (uint32_t)((sqes_per_sqb - 1) * 708 sq->max_sqe_sz)); 709 roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf); 710 sqb_buf = next_sqb; 711 count--; 712 } 713 714 /* Free next to use sqb */ 715 if (rsp->sq.next_sqb) 716 roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb); 717 return 0; 718 } 719 720 static void 721 sq_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, 722 uint16_t smq) 723 { 724 struct mbox *mbox = (&nix->dev)->mbox; 725 struct nix_cn10k_aq_enq_req *aq; 726 727 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 728 aq->qidx = sq->qid; 729 aq->ctype = NIX_AQ_CTYPE_SQ; 730 aq->op = NIX_AQ_INSTOP_INIT; 731 aq->sq.max_sqe_size = sq->max_sqe_sz; 732 733 aq->sq.max_sqe_size = sq->max_sqe_sz; 734 aq->sq.smq = smq; 735 aq->sq.smq_rr_weight = rr_quantum; 736 aq->sq.default_chan = nix->tx_chan_base; 737 aq->sq.sqe_stype = NIX_STYPE_STF; 738 aq->sq.ena = 1; 739 aq->sq.sso_ena = !!sq->sso_ena; 740 if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8) 741 aq->sq.sqe_stype = NIX_STYPE_STP; 742 aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle); 743 aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR); 744 aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL); 745 aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR); 746 aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR); 747 748 /* Many to one reduction */ 749 aq->sq.qint_idx = sq->qid % nix->qints; 750 } 751 752 static int 753 sq_fini(struct nix *nix, struct roc_nix_sq *sq) 754 { 755 struct mbox *mbox = (&nix->dev)->mbox; 756 struct nix_cn10k_aq_enq_rsp *rsp; 757 struct nix_cn10k_aq_enq_req *aq; 758 uint16_t sqes_per_sqb; 759 void *sqb_buf; 760 int rc, count; 761 762 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 763 aq->qidx = sq->qid; 764 aq->ctype = NIX_AQ_CTYPE_SQ; 765 aq->op = NIX_AQ_INSTOP_READ; 766 rc = mbox_process_msg(mbox, (void *)&rsp); 767 if (rc) 768 return rc; 769 770 /* Check if sq is already cleaned up */ 771 if (!rsp->sq.ena) 772 return 0; 773 774 /* Disable sq */ 775 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 776 aq->qidx = sq->qid; 777 aq->ctype = NIX_AQ_CTYPE_SQ; 778 aq->op = NIX_AQ_INSTOP_WRITE; 779 aq->sq_mask.ena = ~aq->sq_mask.ena; 780 aq->sq.ena = 0; 781 rc = mbox_process(mbox); 782 if (rc) 783 return rc; 784 785 /* Read SQ and free sqb's */ 786 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox); 787 aq->qidx = sq->qid; 788 aq->ctype = NIX_AQ_CTYPE_SQ; 789 aq->op = NIX_AQ_INSTOP_READ; 790 rc = mbox_process_msg(mbox, (void *)&rsp); 791 if (rc) 792 return rc; 793 794 if (aq->sq.smq_pend) 795 plt_err("SQ has pending SQE's"); 796 797 count = aq->sq.sqb_count; 798 sqes_per_sqb = 1 << sq->sqes_per_sqb_log2; 799 /* Free SQB's that are used */ 800 sqb_buf = (void *)rsp->sq.head_sqb; 801 while (count) { 802 void *next_sqb; 803 804 next_sqb = *(void **)((uintptr_t)sqb_buf + 805 (uint32_t)((sqes_per_sqb - 1) * 806 sq->max_sqe_sz)); 807 roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf); 808 sqb_buf = next_sqb; 809 count--; 810 } 811 812 /* Free next to use sqb */ 813 if (rsp->sq.next_sqb) 814 roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb); 815 return 0; 816 } 817 818 int 819 roc_nix_sq_init(struct roc_nix *roc_nix, struct roc_nix_sq *sq) 820 { 821 struct nix *nix = roc_nix_to_nix_priv(roc_nix); 822 struct mbox *mbox = (&nix->dev)->mbox; 823 uint16_t qid, smq = UINT16_MAX; 824 uint32_t rr_quantum = 0; 825 int rc; 826 827 if (sq == NULL) 828 return NIX_ERR_PARAM; 829 830 qid = sq->qid; 831 if (qid >= nix->nb_tx_queues) 832 return NIX_ERR_QUEUE_INVALID_RANGE; 833 834 sq->roc_nix = roc_nix; 835 /* 836 * Allocate memory for flow control updates from HW. 837 * Alloc one cache line, so that fits all FC_STYPE modes. 838 */ 839 sq->fc = plt_zmalloc(ROC_ALIGN, ROC_ALIGN); 840 if (sq->fc == NULL) { 841 rc = NIX_ERR_NO_MEM; 842 goto fail; 843 } 844 845 rc = sqb_pool_populate(roc_nix, sq); 846 if (rc) 847 goto nomem; 848 849 rc = nix_tm_leaf_data_get(nix, sq->qid, &rr_quantum, &smq); 850 if (rc) { 851 rc = NIX_ERR_TM_LEAF_NODE_GET; 852 goto nomem; 853 } 854 855 /* Init SQ context */ 856 if (roc_model_is_cn9k()) 857 sq_cn9k_init(nix, sq, rr_quantum, smq); 858 else 859 sq_init(nix, sq, rr_quantum, smq); 860 861 rc = mbox_process(mbox); 862 if (rc) 863 goto nomem; 864 865 nix->sqs[qid] = sq; 866 sq->io_addr = nix->base + NIX_LF_OP_SENDX(0); 867 /* Evenly distribute LMT slot for each sq */ 868 if (roc_model_is_cn9k()) { 869 /* Multiple cores/SQ's can use same LMTLINE safely in CN9K */ 870 sq->lmt_addr = (void *)(nix->lmt_base + 871 ((qid & RVU_CN9K_LMT_SLOT_MASK) << 12)); 872 } 873 874 return rc; 875 nomem: 876 plt_free(sq->fc); 877 fail: 878 return rc; 879 } 880 881 int 882 roc_nix_sq_fini(struct roc_nix_sq *sq) 883 { 884 struct nix *nix; 885 struct mbox *mbox; 886 struct ndc_sync_op *ndc_req; 887 uint16_t qid; 888 int rc = 0; 889 890 if (sq == NULL) 891 return NIX_ERR_PARAM; 892 893 nix = roc_nix_to_nix_priv(sq->roc_nix); 894 mbox = (&nix->dev)->mbox; 895 896 qid = sq->qid; 897 898 rc = nix_tm_sq_flush_pre(sq); 899 900 /* Release SQ context */ 901 if (roc_model_is_cn9k()) 902 rc |= sq_cn9k_fini(roc_nix_to_nix_priv(sq->roc_nix), sq); 903 else 904 rc |= sq_fini(roc_nix_to_nix_priv(sq->roc_nix), sq); 905 906 /* Sync NDC-NIX-TX for LF */ 907 ndc_req = mbox_alloc_msg_ndc_sync_op(mbox); 908 if (ndc_req == NULL) 909 return -ENOSPC; 910 ndc_req->nix_lf_tx_sync = 1; 911 if (mbox_process(mbox)) 912 rc |= NIX_ERR_NDC_SYNC; 913 914 rc |= nix_tm_sq_flush_post(sq); 915 rc |= roc_npa_pool_destroy(sq->aura_handle); 916 plt_free(sq->fc); 917 plt_free(sq->sqe_mem); 918 nix->sqs[qid] = NULL; 919 920 return rc; 921 } 922