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