1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell CN10K MCS driver 3 * 4 * Copyright (C) 2022 Marvell. 5 */ 6 7 #include <linux/types.h> 8 #include <linux/device.h> 9 #include <linux/module.h> 10 #include <linux/pci.h> 11 12 #include "mcs.h" 13 #include "rvu.h" 14 #include "mcs_reg.h" 15 #include "lmac_common.h" 16 17 #define M(_name, _id, _fn_name, _req_type, _rsp_type) \ 18 static struct _req_type __maybe_unused \ 19 *otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid) \ 20 { \ 21 struct _req_type *req; \ 22 \ 23 req = (struct _req_type *)otx2_mbox_alloc_msg_rsp( \ 24 &rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \ 25 sizeof(struct _rsp_type)); \ 26 if (!req) \ 27 return NULL; \ 28 req->hdr.sig = OTX2_MBOX_REQ_SIG; \ 29 req->hdr.id = _id; \ 30 return req; \ 31 } 32 33 MBOX_UP_MCS_MESSAGES 34 #undef M 35 36 void rvu_mcs_ptp_cfg(struct rvu *rvu, u8 rpm_id, u8 lmac_id, bool ena) 37 { 38 struct mcs *mcs; 39 u64 cfg; 40 u8 port; 41 42 if (!rvu->mcs_blk_cnt) 43 return; 44 45 /* When ptp is enabled, RPM appends 8B header for all 46 * RX packets. MCS PEX need to configure to skip 8B 47 * during packet parsing. 48 */ 49 50 /* CNF10K-B */ 51 if (rvu->mcs_blk_cnt > 1) { 52 mcs = mcs_get_pdata(rpm_id); 53 cfg = mcs_reg_read(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION); 54 if (ena) 55 cfg |= BIT_ULL(lmac_id); 56 else 57 cfg &= ~BIT_ULL(lmac_id); 58 mcs_reg_write(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION, cfg); 59 return; 60 } 61 /* CN10KB */ 62 mcs = mcs_get_pdata(0); 63 port = (rpm_id * rvu->hw->lmac_per_cgx) + lmac_id; 64 cfg = mcs_reg_read(mcs, MCSX_PEX_RX_SLAVE_PORT_CFGX(port)); 65 if (ena) 66 cfg |= BIT_ULL(0); 67 else 68 cfg &= ~BIT_ULL(0); 69 mcs_reg_write(mcs, MCSX_PEX_RX_SLAVE_PORT_CFGX(port), cfg); 70 } 71 72 int rvu_mbox_handler_mcs_set_lmac_mode(struct rvu *rvu, 73 struct mcs_set_lmac_mode *req, 74 struct msg_rsp *rsp) 75 { 76 struct mcs *mcs; 77 78 if (req->mcs_id >= rvu->mcs_blk_cnt) 79 return MCS_AF_ERR_INVALID_MCSID; 80 81 mcs = mcs_get_pdata(req->mcs_id); 82 83 if (BIT_ULL(req->lmac_id) & mcs->hw->lmac_bmap) 84 mcs_set_lmac_mode(mcs, req->lmac_id, req->mode); 85 86 return 0; 87 } 88 89 int mcs_add_intr_wq_entry(struct mcs *mcs, struct mcs_intr_event *event) 90 { 91 struct mcs_intrq_entry *qentry; 92 u16 pcifunc = event->pcifunc; 93 struct rvu *rvu = mcs->rvu; 94 struct mcs_pfvf *pfvf; 95 96 /* Check if it is PF or VF */ 97 if (pcifunc & RVU_PFVF_FUNC_MASK) 98 pfvf = &mcs->vf[rvu_get_hwvf(rvu, pcifunc)]; 99 else 100 pfvf = &mcs->pf[rvu_get_pf(pcifunc)]; 101 102 event->intr_mask &= pfvf->intr_mask; 103 104 /* Check PF/VF interrupt notification is enabled */ 105 if (!(pfvf->intr_mask && event->intr_mask)) 106 return 0; 107 108 qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC); 109 if (!qentry) 110 return -ENOMEM; 111 112 qentry->intr_event = *event; 113 spin_lock(&rvu->mcs_intrq_lock); 114 list_add_tail(&qentry->node, &rvu->mcs_intrq_head); 115 spin_unlock(&rvu->mcs_intrq_lock); 116 queue_work(rvu->mcs_intr_wq, &rvu->mcs_intr_work); 117 118 return 0; 119 } 120 121 static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu) 122 { 123 struct mcs_intr_info *req; 124 int pf; 125 126 pf = rvu_get_pf(event->pcifunc); 127 128 mutex_lock(&rvu->mbox_lock); 129 130 req = otx2_mbox_alloc_msg_mcs_intr_notify(rvu, pf); 131 if (!req) { 132 mutex_unlock(&rvu->mbox_lock); 133 return -ENOMEM; 134 } 135 136 req->mcs_id = event->mcs_id; 137 req->intr_mask = event->intr_mask; 138 req->sa_id = event->sa_id; 139 req->hdr.pcifunc = event->pcifunc; 140 req->lmac_id = event->lmac_id; 141 142 otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf); 143 144 otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf); 145 146 mutex_unlock(&rvu->mbox_lock); 147 148 return 0; 149 } 150 151 static void mcs_intr_handler_task(struct work_struct *work) 152 { 153 struct rvu *rvu = container_of(work, struct rvu, mcs_intr_work); 154 struct mcs_intrq_entry *qentry; 155 struct mcs_intr_event *event; 156 unsigned long flags; 157 158 do { 159 spin_lock_irqsave(&rvu->mcs_intrq_lock, flags); 160 qentry = list_first_entry_or_null(&rvu->mcs_intrq_head, 161 struct mcs_intrq_entry, 162 node); 163 if (qentry) 164 list_del(&qentry->node); 165 166 spin_unlock_irqrestore(&rvu->mcs_intrq_lock, flags); 167 if (!qentry) 168 break; /* nothing more to process */ 169 170 event = &qentry->intr_event; 171 172 mcs_notify_pfvf(event, rvu); 173 kfree(qentry); 174 } while (1); 175 } 176 177 int rvu_mbox_handler_mcs_intr_cfg(struct rvu *rvu, 178 struct mcs_intr_cfg *req, 179 struct msg_rsp *rsp) 180 { 181 u16 pcifunc = req->hdr.pcifunc; 182 struct mcs_pfvf *pfvf; 183 struct mcs *mcs; 184 185 if (req->mcs_id >= rvu->mcs_blk_cnt) 186 return MCS_AF_ERR_INVALID_MCSID; 187 188 mcs = mcs_get_pdata(req->mcs_id); 189 190 /* Check if it is PF or VF */ 191 if (pcifunc & RVU_PFVF_FUNC_MASK) 192 pfvf = &mcs->vf[rvu_get_hwvf(rvu, pcifunc)]; 193 else 194 pfvf = &mcs->pf[rvu_get_pf(pcifunc)]; 195 196 mcs->pf_map[0] = pcifunc; 197 pfvf->intr_mask = req->intr_mask; 198 199 return 0; 200 } 201 202 int rvu_mbox_handler_mcs_get_hw_info(struct rvu *rvu, 203 struct msg_req *req, 204 struct mcs_hw_info *rsp) 205 { 206 struct mcs *mcs; 207 208 if (!rvu->mcs_blk_cnt) 209 return MCS_AF_ERR_NOT_MAPPED; 210 211 /* MCS resources are same across all blocks */ 212 mcs = mcs_get_pdata(0); 213 rsp->num_mcs_blks = rvu->mcs_blk_cnt; 214 rsp->tcam_entries = mcs->hw->tcam_entries; 215 rsp->secy_entries = mcs->hw->secy_entries; 216 rsp->sc_entries = mcs->hw->sc_entries; 217 rsp->sa_entries = mcs->hw->sa_entries; 218 return 0; 219 } 220 221 int rvu_mbox_handler_mcs_port_reset(struct rvu *rvu, struct mcs_port_reset_req *req, 222 struct msg_rsp *rsp) 223 { 224 struct mcs *mcs; 225 226 if (req->mcs_id >= rvu->mcs_blk_cnt) 227 return MCS_AF_ERR_INVALID_MCSID; 228 229 mcs = mcs_get_pdata(req->mcs_id); 230 231 mcs_reset_port(mcs, req->port_id, req->reset); 232 233 return 0; 234 } 235 236 int rvu_mbox_handler_mcs_clear_stats(struct rvu *rvu, 237 struct mcs_clear_stats *req, 238 struct msg_rsp *rsp) 239 { 240 u16 pcifunc = req->hdr.pcifunc; 241 struct mcs *mcs; 242 243 if (req->mcs_id >= rvu->mcs_blk_cnt) 244 return MCS_AF_ERR_INVALID_MCSID; 245 246 mcs = mcs_get_pdata(req->mcs_id); 247 248 mutex_lock(&mcs->stats_lock); 249 if (req->all) 250 mcs_clear_all_stats(mcs, pcifunc, req->dir); 251 else 252 mcs_clear_stats(mcs, req->type, req->id, req->dir); 253 254 mutex_unlock(&mcs->stats_lock); 255 return 0; 256 } 257 258 int rvu_mbox_handler_mcs_get_flowid_stats(struct rvu *rvu, 259 struct mcs_stats_req *req, 260 struct mcs_flowid_stats *rsp) 261 { 262 struct mcs *mcs; 263 264 if (req->mcs_id >= rvu->mcs_blk_cnt) 265 return MCS_AF_ERR_INVALID_MCSID; 266 267 mcs = mcs_get_pdata(req->mcs_id); 268 269 /* In CNF10K-B, before reading the statistics, 270 * MCSX_MIL_GLOBAL.FORCE_CLK_EN_IP needs to be set 271 * to get accurate statistics 272 */ 273 if (mcs->hw->mcs_blks > 1) 274 mcs_set_force_clk_en(mcs, true); 275 276 mutex_lock(&mcs->stats_lock); 277 mcs_get_flowid_stats(mcs, rsp, req->id, req->dir); 278 mutex_unlock(&mcs->stats_lock); 279 280 /* Clear MCSX_MIL_GLOBAL.FORCE_CLK_EN_IP after reading 281 * the statistics 282 */ 283 if (mcs->hw->mcs_blks > 1) 284 mcs_set_force_clk_en(mcs, false); 285 286 return 0; 287 } 288 289 int rvu_mbox_handler_mcs_get_secy_stats(struct rvu *rvu, 290 struct mcs_stats_req *req, 291 struct mcs_secy_stats *rsp) 292 { struct mcs *mcs; 293 294 if (req->mcs_id >= rvu->mcs_blk_cnt) 295 return MCS_AF_ERR_INVALID_MCSID; 296 297 mcs = mcs_get_pdata(req->mcs_id); 298 299 if (mcs->hw->mcs_blks > 1) 300 mcs_set_force_clk_en(mcs, true); 301 302 mutex_lock(&mcs->stats_lock); 303 304 if (req->dir == MCS_RX) 305 mcs_get_rx_secy_stats(mcs, rsp, req->id); 306 else 307 mcs_get_tx_secy_stats(mcs, rsp, req->id); 308 309 mutex_unlock(&mcs->stats_lock); 310 311 if (mcs->hw->mcs_blks > 1) 312 mcs_set_force_clk_en(mcs, false); 313 314 return 0; 315 } 316 317 int rvu_mbox_handler_mcs_get_sc_stats(struct rvu *rvu, 318 struct mcs_stats_req *req, 319 struct mcs_sc_stats *rsp) 320 { 321 struct mcs *mcs; 322 323 if (req->mcs_id >= rvu->mcs_blk_cnt) 324 return MCS_AF_ERR_INVALID_MCSID; 325 326 mcs = mcs_get_pdata(req->mcs_id); 327 328 if (mcs->hw->mcs_blks > 1) 329 mcs_set_force_clk_en(mcs, true); 330 331 mutex_lock(&mcs->stats_lock); 332 mcs_get_sc_stats(mcs, rsp, req->id, req->dir); 333 mutex_unlock(&mcs->stats_lock); 334 335 if (mcs->hw->mcs_blks > 1) 336 mcs_set_force_clk_en(mcs, false); 337 338 return 0; 339 } 340 341 int rvu_mbox_handler_mcs_get_sa_stats(struct rvu *rvu, 342 struct mcs_stats_req *req, 343 struct mcs_sa_stats *rsp) 344 { 345 struct mcs *mcs; 346 347 if (req->mcs_id >= rvu->mcs_blk_cnt) 348 return MCS_AF_ERR_INVALID_MCSID; 349 350 mcs = mcs_get_pdata(req->mcs_id); 351 352 if (mcs->hw->mcs_blks > 1) 353 mcs_set_force_clk_en(mcs, true); 354 355 mutex_lock(&mcs->stats_lock); 356 mcs_get_sa_stats(mcs, rsp, req->id, req->dir); 357 mutex_unlock(&mcs->stats_lock); 358 359 if (mcs->hw->mcs_blks > 1) 360 mcs_set_force_clk_en(mcs, false); 361 362 return 0; 363 } 364 365 int rvu_mbox_handler_mcs_get_port_stats(struct rvu *rvu, 366 struct mcs_stats_req *req, 367 struct mcs_port_stats *rsp) 368 { 369 struct mcs *mcs; 370 371 if (req->mcs_id >= rvu->mcs_blk_cnt) 372 return MCS_AF_ERR_INVALID_MCSID; 373 374 mcs = mcs_get_pdata(req->mcs_id); 375 376 if (mcs->hw->mcs_blks > 1) 377 mcs_set_force_clk_en(mcs, true); 378 379 mutex_lock(&mcs->stats_lock); 380 mcs_get_port_stats(mcs, rsp, req->id, req->dir); 381 mutex_unlock(&mcs->stats_lock); 382 383 if (mcs->hw->mcs_blks > 1) 384 mcs_set_force_clk_en(mcs, false); 385 386 return 0; 387 } 388 389 int rvu_mbox_handler_mcs_set_active_lmac(struct rvu *rvu, 390 struct mcs_set_active_lmac *req, 391 struct msg_rsp *rsp) 392 { 393 struct mcs *mcs; 394 395 if (req->mcs_id >= rvu->mcs_blk_cnt) 396 return MCS_AF_ERR_INVALID_MCSID; 397 398 mcs = mcs_get_pdata(req->mcs_id); 399 if (!mcs) 400 return MCS_AF_ERR_NOT_MAPPED; 401 402 mcs->hw->lmac_bmap = req->lmac_bmap; 403 mcs_set_lmac_channels(req->mcs_id, req->chan_base); 404 return 0; 405 } 406 407 int rvu_mbox_handler_mcs_port_cfg_set(struct rvu *rvu, struct mcs_port_cfg_set_req *req, 408 struct msg_rsp *rsp) 409 { 410 struct mcs *mcs; 411 412 if (req->mcs_id >= rvu->mcs_blk_cnt) 413 return MCS_AF_ERR_INVALID_MCSID; 414 415 mcs = mcs_get_pdata(req->mcs_id); 416 417 if (mcs->hw->lmac_cnt <= req->port_id || !(mcs->hw->lmac_bmap & BIT_ULL(req->port_id))) 418 return -EINVAL; 419 420 mcs_set_port_cfg(mcs, req); 421 422 return 0; 423 } 424 425 int rvu_mbox_handler_mcs_port_cfg_get(struct rvu *rvu, struct mcs_port_cfg_get_req *req, 426 struct mcs_port_cfg_get_rsp *rsp) 427 { 428 struct mcs *mcs; 429 430 if (req->mcs_id >= rvu->mcs_blk_cnt) 431 return MCS_AF_ERR_INVALID_MCSID; 432 433 mcs = mcs_get_pdata(req->mcs_id); 434 435 if (mcs->hw->lmac_cnt <= req->port_id || !(mcs->hw->lmac_bmap & BIT_ULL(req->port_id))) 436 return -EINVAL; 437 438 mcs_get_port_cfg(mcs, req, rsp); 439 440 return 0; 441 } 442 443 int rvu_mbox_handler_mcs_custom_tag_cfg_get(struct rvu *rvu, struct mcs_custom_tag_cfg_get_req *req, 444 struct mcs_custom_tag_cfg_get_rsp *rsp) 445 { 446 struct mcs *mcs; 447 448 if (req->mcs_id >= rvu->mcs_blk_cnt) 449 return MCS_AF_ERR_INVALID_MCSID; 450 451 mcs = mcs_get_pdata(req->mcs_id); 452 453 mcs_get_custom_tag_cfg(mcs, req, rsp); 454 455 return 0; 456 } 457 458 int rvu_mcs_flr_handler(struct rvu *rvu, u16 pcifunc) 459 { 460 struct mcs *mcs; 461 int mcs_id; 462 463 /* CNF10K-B mcs0-6 are mapped to RPM2-8*/ 464 if (rvu->mcs_blk_cnt > 1) { 465 for (mcs_id = 0; mcs_id < rvu->mcs_blk_cnt; mcs_id++) { 466 mcs = mcs_get_pdata(mcs_id); 467 mcs_free_all_rsrc(mcs, MCS_RX, pcifunc); 468 mcs_free_all_rsrc(mcs, MCS_TX, pcifunc); 469 } 470 } else { 471 /* CN10K-B has only one mcs block */ 472 mcs = mcs_get_pdata(0); 473 mcs_free_all_rsrc(mcs, MCS_RX, pcifunc); 474 mcs_free_all_rsrc(mcs, MCS_TX, pcifunc); 475 } 476 return 0; 477 } 478 479 int rvu_mbox_handler_mcs_flowid_ena_entry(struct rvu *rvu, 480 struct mcs_flowid_ena_dis_entry *req, 481 struct msg_rsp *rsp) 482 { 483 struct mcs *mcs; 484 485 if (req->mcs_id >= rvu->mcs_blk_cnt) 486 return MCS_AF_ERR_INVALID_MCSID; 487 488 mcs = mcs_get_pdata(req->mcs_id); 489 mcs_ena_dis_flowid_entry(mcs, req->flow_id, req->dir, req->ena); 490 return 0; 491 } 492 493 int rvu_mbox_handler_mcs_pn_table_write(struct rvu *rvu, 494 struct mcs_pn_table_write_req *req, 495 struct msg_rsp *rsp) 496 { 497 struct mcs *mcs; 498 499 if (req->mcs_id >= rvu->mcs_blk_cnt) 500 return MCS_AF_ERR_INVALID_MCSID; 501 502 mcs = mcs_get_pdata(req->mcs_id); 503 mcs_pn_table_write(mcs, req->pn_id, req->next_pn, req->dir); 504 return 0; 505 } 506 507 int rvu_mbox_handler_mcs_set_pn_threshold(struct rvu *rvu, 508 struct mcs_set_pn_threshold *req, 509 struct msg_rsp *rsp) 510 { 511 struct mcs *mcs; 512 513 if (req->mcs_id >= rvu->mcs_blk_cnt) 514 return MCS_AF_ERR_INVALID_MCSID; 515 516 mcs = mcs_get_pdata(req->mcs_id); 517 518 mcs_pn_threshold_set(mcs, req); 519 520 return 0; 521 } 522 523 int rvu_mbox_handler_mcs_rx_sc_sa_map_write(struct rvu *rvu, 524 struct mcs_rx_sc_sa_map *req, 525 struct msg_rsp *rsp) 526 { 527 struct mcs *mcs; 528 529 if (req->mcs_id >= rvu->mcs_blk_cnt) 530 return MCS_AF_ERR_INVALID_MCSID; 531 532 mcs = mcs_get_pdata(req->mcs_id); 533 mcs->mcs_ops->mcs_rx_sa_mem_map_write(mcs, req); 534 return 0; 535 } 536 537 int rvu_mbox_handler_mcs_tx_sc_sa_map_write(struct rvu *rvu, 538 struct mcs_tx_sc_sa_map *req, 539 struct msg_rsp *rsp) 540 { 541 struct mcs *mcs; 542 543 if (req->mcs_id >= rvu->mcs_blk_cnt) 544 return MCS_AF_ERR_INVALID_MCSID; 545 546 mcs = mcs_get_pdata(req->mcs_id); 547 mcs->mcs_ops->mcs_tx_sa_mem_map_write(mcs, req); 548 mcs->tx_sa_active[req->sc_id] = req->tx_sa_active; 549 550 return 0; 551 } 552 553 int rvu_mbox_handler_mcs_sa_plcy_write(struct rvu *rvu, 554 struct mcs_sa_plcy_write_req *req, 555 struct msg_rsp *rsp) 556 { 557 struct mcs *mcs; 558 int i; 559 560 if (req->mcs_id >= rvu->mcs_blk_cnt) 561 return MCS_AF_ERR_INVALID_MCSID; 562 563 mcs = mcs_get_pdata(req->mcs_id); 564 565 for (i = 0; i < req->sa_cnt; i++) 566 mcs_sa_plcy_write(mcs, &req->plcy[i][0], 567 req->sa_index[i], req->dir); 568 return 0; 569 } 570 571 int rvu_mbox_handler_mcs_rx_sc_cam_write(struct rvu *rvu, 572 struct mcs_rx_sc_cam_write_req *req, 573 struct msg_rsp *rsp) 574 { 575 struct mcs *mcs; 576 577 if (req->mcs_id >= rvu->mcs_blk_cnt) 578 return MCS_AF_ERR_INVALID_MCSID; 579 580 mcs = mcs_get_pdata(req->mcs_id); 581 mcs_rx_sc_cam_write(mcs, req->sci, req->secy_id, req->sc_id); 582 return 0; 583 } 584 585 int rvu_mbox_handler_mcs_secy_plcy_write(struct rvu *rvu, 586 struct mcs_secy_plcy_write_req *req, 587 struct msg_rsp *rsp) 588 { struct mcs *mcs; 589 590 if (req->mcs_id >= rvu->mcs_blk_cnt) 591 return MCS_AF_ERR_INVALID_MCSID; 592 593 mcs = mcs_get_pdata(req->mcs_id); 594 595 mcs_secy_plcy_write(mcs, req->plcy, 596 req->secy_id, req->dir); 597 return 0; 598 } 599 600 int rvu_mbox_handler_mcs_flowid_entry_write(struct rvu *rvu, 601 struct mcs_flowid_entry_write_req *req, 602 struct msg_rsp *rsp) 603 { 604 struct secy_mem_map map; 605 struct mcs *mcs; 606 607 if (req->mcs_id >= rvu->mcs_blk_cnt) 608 return MCS_AF_ERR_INVALID_MCSID; 609 610 mcs = mcs_get_pdata(req->mcs_id); 611 612 /* TODO validate the flowid */ 613 mcs_flowid_entry_write(mcs, req->data, req->mask, 614 req->flow_id, req->dir); 615 map.secy = req->secy_id; 616 map.sc = req->sc_id; 617 map.ctrl_pkt = req->ctrl_pkt; 618 map.flow_id = req->flow_id; 619 map.sci = req->sci; 620 mcs->mcs_ops->mcs_flowid_secy_map(mcs, &map, req->dir); 621 if (req->ena) 622 mcs_ena_dis_flowid_entry(mcs, req->flow_id, 623 req->dir, true); 624 return 0; 625 } 626 627 int rvu_mbox_handler_mcs_free_resources(struct rvu *rvu, 628 struct mcs_free_rsrc_req *req, 629 struct msg_rsp *rsp) 630 { 631 u16 pcifunc = req->hdr.pcifunc; 632 struct mcs_rsrc_map *map; 633 struct mcs *mcs; 634 int rc = 0; 635 636 if (req->mcs_id >= rvu->mcs_blk_cnt) 637 return MCS_AF_ERR_INVALID_MCSID; 638 639 mcs = mcs_get_pdata(req->mcs_id); 640 641 if (req->dir == MCS_RX) 642 map = &mcs->rx; 643 else 644 map = &mcs->tx; 645 646 mutex_lock(&rvu->rsrc_lock); 647 /* Free all the cam resources mapped to PF/VF */ 648 if (req->all) { 649 rc = mcs_free_all_rsrc(mcs, req->dir, pcifunc); 650 goto exit; 651 } 652 653 switch (req->rsrc_type) { 654 case MCS_RSRC_TYPE_FLOWID: 655 rc = mcs_free_rsrc(&map->flow_ids, map->flowid2pf_map, req->rsrc_id, pcifunc); 656 mcs_ena_dis_flowid_entry(mcs, req->rsrc_id, req->dir, false); 657 break; 658 case MCS_RSRC_TYPE_SECY: 659 rc = mcs_free_rsrc(&map->secy, map->secy2pf_map, req->rsrc_id, pcifunc); 660 mcs_clear_secy_plcy(mcs, req->rsrc_id, req->dir); 661 break; 662 case MCS_RSRC_TYPE_SC: 663 rc = mcs_free_rsrc(&map->sc, map->sc2pf_map, req->rsrc_id, pcifunc); 664 /* Disable SC CAM only on RX side */ 665 if (req->dir == MCS_RX) 666 mcs_ena_dis_sc_cam_entry(mcs, req->rsrc_id, false); 667 break; 668 case MCS_RSRC_TYPE_SA: 669 rc = mcs_free_rsrc(&map->sa, map->sa2pf_map, req->rsrc_id, pcifunc); 670 break; 671 } 672 exit: 673 mutex_unlock(&rvu->rsrc_lock); 674 return rc; 675 } 676 677 int rvu_mbox_handler_mcs_alloc_resources(struct rvu *rvu, 678 struct mcs_alloc_rsrc_req *req, 679 struct mcs_alloc_rsrc_rsp *rsp) 680 { 681 u16 pcifunc = req->hdr.pcifunc; 682 struct mcs_rsrc_map *map; 683 struct mcs *mcs; 684 int rsrc_id, i; 685 686 if (req->mcs_id >= rvu->mcs_blk_cnt) 687 return MCS_AF_ERR_INVALID_MCSID; 688 689 mcs = mcs_get_pdata(req->mcs_id); 690 691 if (req->dir == MCS_RX) 692 map = &mcs->rx; 693 else 694 map = &mcs->tx; 695 696 mutex_lock(&rvu->rsrc_lock); 697 698 if (req->all) { 699 rsrc_id = mcs_alloc_all_rsrc(mcs, &rsp->flow_ids[0], 700 &rsp->secy_ids[0], 701 &rsp->sc_ids[0], 702 &rsp->sa_ids[0], 703 &rsp->sa_ids[1], 704 pcifunc, req->dir); 705 goto exit; 706 } 707 708 switch (req->rsrc_type) { 709 case MCS_RSRC_TYPE_FLOWID: 710 for (i = 0; i < req->rsrc_cnt; i++) { 711 rsrc_id = mcs_alloc_rsrc(&map->flow_ids, map->flowid2pf_map, pcifunc); 712 if (rsrc_id < 0) 713 goto exit; 714 rsp->flow_ids[i] = rsrc_id; 715 rsp->rsrc_cnt++; 716 } 717 break; 718 case MCS_RSRC_TYPE_SECY: 719 for (i = 0; i < req->rsrc_cnt; i++) { 720 rsrc_id = mcs_alloc_rsrc(&map->secy, map->secy2pf_map, pcifunc); 721 if (rsrc_id < 0) 722 goto exit; 723 rsp->secy_ids[i] = rsrc_id; 724 rsp->rsrc_cnt++; 725 } 726 break; 727 case MCS_RSRC_TYPE_SC: 728 for (i = 0; i < req->rsrc_cnt; i++) { 729 rsrc_id = mcs_alloc_rsrc(&map->sc, map->sc2pf_map, pcifunc); 730 if (rsrc_id < 0) 731 goto exit; 732 rsp->sc_ids[i] = rsrc_id; 733 rsp->rsrc_cnt++; 734 } 735 break; 736 case MCS_RSRC_TYPE_SA: 737 for (i = 0; i < req->rsrc_cnt; i++) { 738 rsrc_id = mcs_alloc_rsrc(&map->sa, map->sa2pf_map, pcifunc); 739 if (rsrc_id < 0) 740 goto exit; 741 rsp->sa_ids[i] = rsrc_id; 742 rsp->rsrc_cnt++; 743 } 744 break; 745 } 746 747 rsp->rsrc_type = req->rsrc_type; 748 rsp->dir = req->dir; 749 rsp->mcs_id = req->mcs_id; 750 rsp->all = req->all; 751 752 exit: 753 if (rsrc_id < 0) 754 dev_err(rvu->dev, "Failed to allocate the mcs resources for PCIFUNC:%d\n", pcifunc); 755 mutex_unlock(&rvu->rsrc_lock); 756 return 0; 757 } 758 759 int rvu_mbox_handler_mcs_alloc_ctrl_pkt_rule(struct rvu *rvu, 760 struct mcs_alloc_ctrl_pkt_rule_req *req, 761 struct mcs_alloc_ctrl_pkt_rule_rsp *rsp) 762 { 763 u16 pcifunc = req->hdr.pcifunc; 764 struct mcs_rsrc_map *map; 765 struct mcs *mcs; 766 int rsrc_id; 767 u16 offset; 768 769 if (req->mcs_id >= rvu->mcs_blk_cnt) 770 return MCS_AF_ERR_INVALID_MCSID; 771 772 mcs = mcs_get_pdata(req->mcs_id); 773 774 map = (req->dir == MCS_RX) ? &mcs->rx : &mcs->tx; 775 776 mutex_lock(&rvu->rsrc_lock); 777 778 switch (req->rule_type) { 779 case MCS_CTRL_PKT_RULE_TYPE_ETH: 780 offset = MCS_CTRLPKT_ETYPE_RULE_OFFSET; 781 break; 782 case MCS_CTRL_PKT_RULE_TYPE_DA: 783 offset = MCS_CTRLPKT_DA_RULE_OFFSET; 784 break; 785 case MCS_CTRL_PKT_RULE_TYPE_RANGE: 786 offset = MCS_CTRLPKT_DA_RANGE_RULE_OFFSET; 787 break; 788 case MCS_CTRL_PKT_RULE_TYPE_COMBO: 789 offset = MCS_CTRLPKT_COMBO_RULE_OFFSET; 790 break; 791 case MCS_CTRL_PKT_RULE_TYPE_MAC: 792 offset = MCS_CTRLPKT_MAC_EN_RULE_OFFSET; 793 break; 794 } 795 796 rsrc_id = mcs_alloc_ctrlpktrule(&map->ctrlpktrule, map->ctrlpktrule2pf_map, offset, 797 pcifunc); 798 if (rsrc_id < 0) 799 goto exit; 800 801 rsp->rule_idx = rsrc_id; 802 rsp->rule_type = req->rule_type; 803 rsp->dir = req->dir; 804 rsp->mcs_id = req->mcs_id; 805 806 mutex_unlock(&rvu->rsrc_lock); 807 return 0; 808 exit: 809 if (rsrc_id < 0) 810 dev_err(rvu->dev, "Failed to allocate the mcs ctrl pkt rule for PCIFUNC:%d\n", 811 pcifunc); 812 mutex_unlock(&rvu->rsrc_lock); 813 return rsrc_id; 814 } 815 816 int rvu_mbox_handler_mcs_free_ctrl_pkt_rule(struct rvu *rvu, 817 struct mcs_free_ctrl_pkt_rule_req *req, 818 struct msg_rsp *rsp) 819 { 820 struct mcs *mcs; 821 int rc; 822 823 if (req->mcs_id >= rvu->mcs_blk_cnt) 824 return MCS_AF_ERR_INVALID_MCSID; 825 826 mcs = mcs_get_pdata(req->mcs_id); 827 828 mutex_lock(&rvu->rsrc_lock); 829 830 rc = mcs_free_ctrlpktrule(mcs, req); 831 832 mutex_unlock(&rvu->rsrc_lock); 833 834 return rc; 835 } 836 837 int rvu_mbox_handler_mcs_ctrl_pkt_rule_write(struct rvu *rvu, 838 struct mcs_ctrl_pkt_rule_write_req *req, 839 struct msg_rsp *rsp) 840 { 841 struct mcs *mcs; 842 int rc; 843 844 if (req->mcs_id >= rvu->mcs_blk_cnt) 845 return MCS_AF_ERR_INVALID_MCSID; 846 847 mcs = mcs_get_pdata(req->mcs_id); 848 849 rc = mcs_ctrlpktrule_write(mcs, req); 850 851 return rc; 852 } 853 854 static void rvu_mcs_set_lmac_bmap(struct rvu *rvu) 855 { 856 struct mcs *mcs = mcs_get_pdata(0); 857 unsigned long lmac_bmap; 858 int cgx, lmac, port; 859 860 for (port = 0; port < mcs->hw->lmac_cnt; port++) { 861 cgx = port / rvu->hw->lmac_per_cgx; 862 lmac = port % rvu->hw->lmac_per_cgx; 863 if (!is_lmac_valid(rvu_cgx_pdata(cgx, rvu), lmac)) 864 continue; 865 set_bit(port, &lmac_bmap); 866 } 867 mcs->hw->lmac_bmap = lmac_bmap; 868 } 869 870 int rvu_mcs_init(struct rvu *rvu) 871 { 872 struct rvu_hwinfo *hw = rvu->hw; 873 int lmac, err = 0, mcs_id; 874 struct mcs *mcs; 875 876 rvu->mcs_blk_cnt = mcs_get_blkcnt(); 877 878 if (!rvu->mcs_blk_cnt) 879 return 0; 880 881 /* Needed only for CN10K-B */ 882 if (rvu->mcs_blk_cnt == 1) { 883 err = mcs_set_lmac_channels(0, hw->cgx_chan_base); 884 if (err) 885 return err; 886 /* Set active lmacs */ 887 rvu_mcs_set_lmac_bmap(rvu); 888 } 889 890 /* Install default tcam bypass entry and set port to operational mode */ 891 for (mcs_id = 0; mcs_id < rvu->mcs_blk_cnt; mcs_id++) { 892 mcs = mcs_get_pdata(mcs_id); 893 mcs_install_flowid_bypass_entry(mcs); 894 for (lmac = 0; lmac < mcs->hw->lmac_cnt; lmac++) 895 mcs_set_lmac_mode(mcs, lmac, 0); 896 897 mcs->rvu = rvu; 898 899 /* Allocated memory for PFVF data */ 900 mcs->pf = devm_kcalloc(mcs->dev, hw->total_pfs, 901 sizeof(struct mcs_pfvf), GFP_KERNEL); 902 if (!mcs->pf) 903 return -ENOMEM; 904 905 mcs->vf = devm_kcalloc(mcs->dev, hw->total_vfs, 906 sizeof(struct mcs_pfvf), GFP_KERNEL); 907 if (!mcs->vf) 908 return -ENOMEM; 909 } 910 911 /* Initialize the wq for handling mcs interrupts */ 912 INIT_LIST_HEAD(&rvu->mcs_intrq_head); 913 INIT_WORK(&rvu->mcs_intr_work, mcs_intr_handler_task); 914 rvu->mcs_intr_wq = alloc_workqueue("mcs_intr_wq", 0, 0); 915 if (!rvu->mcs_intr_wq) { 916 dev_err(rvu->dev, "mcs alloc workqueue failed\n"); 917 return -ENOMEM; 918 } 919 920 return err; 921 } 922 923 void rvu_mcs_exit(struct rvu *rvu) 924 { 925 if (!rvu->mcs_intr_wq) 926 return; 927 928 flush_workqueue(rvu->mcs_intr_wq); 929 destroy_workqueue(rvu->mcs_intr_wq); 930 rvu->mcs_intr_wq = NULL; 931 } 932