1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright (c) 2023, Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the Intel Corporation nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /** 33 * @file ice_rdma.c 34 * @brief RDMA client driver interface 35 * 36 * Functions to interface with the RDMA client driver, for enabling RMDA 37 * functionality for the ice driver. 38 * 39 * The RDMA client interface is based on a simple kobject interface which is 40 * defined by the rmda_if.m and irdma_di_if.m interfaces. 41 * 42 * The ice device driver provides the rmda_di_if.m interface methods, while 43 * the client RDMA driver provides the irdma_if.m interface methods as an 44 * extension ontop of the irdma_di_if kobject. 45 * 46 * The initial connection between drivers is done via the RDMA client driver 47 * calling ice_rdma_register. 48 */ 49 50 #include "ice_iflib.h" 51 #include "ice_rdma_internal.h" 52 53 #include "irdma_if.h" 54 #include "irdma_di_if.h" 55 56 /** 57 * @var ice_rdma 58 * @brief global RDMA driver state 59 * 60 * Contains global state the driver uses to connect to a client RDMA interface 61 * driver. 62 */ 63 static struct ice_rdma_state ice_rdma; 64 65 /* 66 * Helper function prototypes 67 */ 68 static int ice_rdma_pf_attach_locked(struct ice_softc *sc); 69 static void ice_rdma_pf_detach_locked(struct ice_softc *sc); 70 static int ice_rdma_check_version(struct ice_rdma_info *info); 71 static void ice_rdma_cp_qos_info(struct ice_hw *hw, 72 struct ice_dcbx_cfg *dcbx_cfg, 73 struct ice_qos_params *qos_info); 74 75 /* 76 * RDMA Device Interface prototypes 77 */ 78 static int ice_rdma_pf_reset(struct ice_rdma_peer *peer); 79 static int ice_rdma_pf_msix_init(struct ice_rdma_peer *peer, 80 struct ice_rdma_msix_mapping *msix_info); 81 static int ice_rdma_qset_register_request(struct ice_rdma_peer *peer, 82 struct ice_rdma_qset_update *res); 83 static int ice_rdma_update_vsi_filter(struct ice_rdma_peer *peer_dev, 84 bool enable); 85 static void ice_rdma_request_handler(struct ice_rdma_peer *peer, 86 struct ice_rdma_request *req); 87 88 89 /** 90 * @var ice_rdma_di_methods 91 * @brief RDMA driver interface methods 92 * 93 * Kobject methods implementing the driver-side interface for the RDMA peer 94 * clients. This method table contains the operations which the client can 95 * request from the driver. 96 * 97 * The client driver will then extend this kobject class with methods that the 98 * driver can request from the client. 99 */ 100 static kobj_method_t ice_rdma_di_methods[] = { 101 KOBJMETHOD(irdma_di_reset, ice_rdma_pf_reset), 102 KOBJMETHOD(irdma_di_msix_init, ice_rdma_pf_msix_init), 103 KOBJMETHOD(irdma_di_qset_register_request, ice_rdma_qset_register_request), 104 KOBJMETHOD(irdma_di_vsi_filter_update, ice_rdma_update_vsi_filter), 105 KOBJMETHOD(irdma_di_req_handler, ice_rdma_request_handler), 106 KOBJMETHOD_END 107 }; 108 109 /* Define ice_rdma_di class which will be extended by the iRDMA driver */ 110 DEFINE_CLASS_0(ice_rdma_di, ice_rdma_di_class, ice_rdma_di_methods, sizeof(struct ice_rdma_peer)); 111 112 /** 113 * ice_rdma_pf_reset - RDMA client interface requested a reset 114 * @peer: the RDMA peer client structure 115 * 116 * Implements IRDMA_DI_RESET, called by the RDMA client driver to request 117 * a reset of an ice driver device. 118 */ 119 static int 120 ice_rdma_pf_reset(struct ice_rdma_peer *peer) 121 { 122 struct ice_softc *sc = ice_rdma_peer_to_sc(peer); 123 124 /* Tell the base driver that RDMA is requesting a PFR */ 125 ice_set_state(&sc->state, ICE_STATE_RESET_PFR_REQ); 126 127 /* XXX: Base driver will notify RDMA when it's done */ 128 129 return (0); 130 } 131 132 /** 133 * ice_rdma_pf_msix_init - RDMA client interface request MSI-X initialization 134 * @peer: the RDMA peer client structure 135 * @msix_info: requested MSI-X mapping 136 * 137 * Implements IRDMA_DI_MSIX_INIT, called by the RDMA client driver to 138 * initialize the MSI-X resources required for RDMA functionality. 139 */ 140 static int 141 ice_rdma_pf_msix_init(struct ice_rdma_peer *peer, 142 struct ice_rdma_msix_mapping __unused *msix_info) 143 { 144 struct ice_softc *sc = ice_rdma_peer_to_sc(peer); 145 146 MPASS(msix_info != NULL); 147 148 device_printf(sc->dev, "%s: iRDMA MSI-X initialization request is not yet implemented\n", __func__); 149 150 /* TODO: implement MSI-X initialization for RDMA */ 151 return (ENOSYS); 152 } 153 154 /** 155 * ice_rdma_register_request - RDMA client interface request qset 156 * registration or unregistration 157 * @peer: the RDMA peer client structure 158 * @res: resources to be registered or unregistered 159 */ 160 static int 161 ice_rdma_qset_register_request(struct ice_rdma_peer *peer, struct ice_rdma_qset_update *res) 162 { 163 struct ice_softc *sc = ice_rdma_peer_to_sc(peer); 164 struct ice_vsi *vsi = NULL; 165 struct ice_dcbx_cfg *dcbx_cfg; 166 struct ice_hw *hw = &sc->hw; 167 enum ice_status status; 168 int count, i, ret = 0; 169 uint32_t *qset_teid; 170 uint16_t *qs_handle; 171 uint16_t max_rdmaqs[ICE_MAX_TRAFFIC_CLASS]; 172 uint16_t vsi_id; 173 uint8_t ena_tc = 0; 174 175 if (!res) 176 return -EINVAL; 177 178 if (res->cnt_req > ICE_MAX_TXQ_PER_TXQG) 179 return -EINVAL; 180 181 switch(res->res_type) { 182 case ICE_RDMA_QSET_ALLOC: 183 count = res->cnt_req; 184 vsi_id = peer->pf_vsi_num; 185 break; 186 case ICE_RDMA_QSET_FREE: 187 count = res->res_allocated; 188 vsi_id = res->qsets.vsi_id; 189 break; 190 default: 191 return -EINVAL; 192 } 193 qset_teid = (uint32_t *)ice_calloc(hw, count, sizeof(*qset_teid)); 194 if (!qset_teid) 195 return -ENOMEM; 196 197 qs_handle = (uint16_t *)ice_calloc(hw, count, sizeof(*qs_handle)); 198 if (!qs_handle) { 199 ice_free(hw, qset_teid); 200 return -ENOMEM; 201 } 202 203 ice_for_each_traffic_class(i) 204 max_rdmaqs[i] = 0; 205 for (i = 0; i < sc->num_available_vsi; i++) { 206 if (sc->all_vsi[i] && 207 ice_get_hw_vsi_num(hw, sc->all_vsi[i]->idx) == vsi_id) { 208 vsi = sc->all_vsi[i]; 209 break; 210 } 211 } 212 213 if (!vsi) { 214 ice_debug(hw, ICE_DBG_RDMA, "RDMA QSet invalid VSI\n"); 215 ret = -EINVAL; 216 goto out; 217 } 218 if (sc != vsi->sc) { 219 ice_debug(hw, ICE_DBG_RDMA, "VSI is tied to unexpected device\n"); 220 ret = -EXDEV; 221 goto out; 222 } 223 224 for (i = 0; i < count; i++) { 225 struct ice_rdma_qset_params *qset; 226 227 qset = &res->qsets; 228 if (qset->vsi_id != peer->pf_vsi_num) { 229 ice_debug(hw, ICE_DBG_RDMA, "RDMA QSet invalid VSI requested %d %d\n", 230 qset->vsi_id, peer->pf_vsi_num); 231 ret = -EINVAL; 232 goto out; 233 } 234 max_rdmaqs[qset->tc]++; 235 qs_handle[i] = qset->qs_handle; 236 qset_teid[i] = qset->teid; 237 } 238 239 switch(res->res_type) { 240 case ICE_RDMA_QSET_ALLOC: 241 dcbx_cfg = &hw->port_info->qos_cfg.local_dcbx_cfg; 242 ena_tc = ice_dcb_get_tc_map(dcbx_cfg); 243 244 ice_debug(hw, ICE_DBG_RDMA, "%s:%d ena_tc=%x\n", __func__, __LINE__, ena_tc); 245 status = ice_cfg_vsi_rdma(hw->port_info, vsi->idx, ena_tc, 246 max_rdmaqs); 247 if (status) { 248 ice_debug(hw, ICE_DBG_RDMA, "Failed VSI RDMA qset config\n"); 249 ret = -EINVAL; 250 goto out; 251 } 252 253 for (i = 0; i < count; i++) { 254 struct ice_rdma_qset_params *qset; 255 256 qset = &res->qsets; 257 status = ice_ena_vsi_rdma_qset(hw->port_info, vsi->idx, 258 qset->tc, &qs_handle[i], 1, 259 &qset_teid[i]); 260 if (status) { 261 ice_debug(hw, ICE_DBG_RDMA, "Failed VSI RDMA qset enable\n"); 262 ret = -EINVAL; 263 goto out; 264 } 265 qset->teid = qset_teid[i]; 266 } 267 break; 268 case ICE_RDMA_QSET_FREE: 269 status = ice_dis_vsi_rdma_qset(hw->port_info, count, qset_teid, qs_handle); 270 if (status) 271 ret = -EINVAL; 272 break; 273 default: 274 ret = -EINVAL; 275 break; 276 } 277 278 out: 279 ice_free(hw, qs_handle); 280 ice_free(hw, qset_teid); 281 282 return ret; 283 } 284 285 /** 286 * ice_rdma_update_vsi_filter - configure vsi information 287 * when opening or closing rdma driver 288 * @peer: the RDMA peer client structure 289 * @enable: enable or disable the rdma filter 290 */ 291 static int 292 ice_rdma_update_vsi_filter(struct ice_rdma_peer *peer, 293 bool enable) 294 { 295 struct ice_softc *sc = ice_rdma_peer_to_sc(peer); 296 struct ice_vsi *vsi; 297 int ret; 298 299 vsi = &sc->pf_vsi; 300 if (!vsi) 301 return -EINVAL; 302 303 ret = ice_cfg_iwarp_fltr(&sc->hw, vsi->idx, enable); 304 if (ret) { 305 device_printf(sc->dev, "Failed to %sable iWARP filtering\n", 306 enable ? "en" : "dis"); 307 } else { 308 if (enable) 309 vsi->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 310 else 311 vsi->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 312 } 313 314 return ret; 315 } 316 317 /** 318 * ice_rdma_request_handler - handle requests incoming from RDMA driver 319 * @peer: the RDMA peer client structure 320 * @req: structure containing request 321 */ 322 static void 323 ice_rdma_request_handler(struct ice_rdma_peer *peer, 324 struct ice_rdma_request *req) 325 { 326 if (!req || !peer) { 327 log(LOG_WARNING, "%s: peer or req are not valid\n", __func__); 328 return; 329 } 330 331 switch(req->type) { 332 case ICE_RDMA_EVENT_RESET: 333 ice_rdma_pf_reset(peer); 334 break; 335 case ICE_RDMA_EVENT_QSET_REGISTER: 336 ice_rdma_qset_register_request(peer, &req->res); 337 break; 338 case ICE_RDMA_EVENT_VSI_FILTER_UPDATE: 339 ice_rdma_update_vsi_filter(peer, req->enable_filter); 340 break; 341 default: 342 log(LOG_WARNING, "%s: Event %d not supported\n", __func__, req->type); 343 break; 344 } 345 } 346 347 /** 348 * ice_rdma_cp_qos_info - gather current QOS/DCB settings in LAN to pass 349 * to RDMA driver 350 * @hw: ice hw structure 351 * @dcbx_cfg: current DCB settings in ice driver 352 * @qos_info: destination of the DCB settings 353 */ 354 static void 355 ice_rdma_cp_qos_info(struct ice_hw *hw, struct ice_dcbx_cfg *dcbx_cfg, 356 struct ice_qos_params *qos_info) 357 { 358 u32 up2tc; 359 u8 j; 360 u8 num_tc = 0; 361 u8 val_tc = 0; /* number of TC for validation */ 362 u8 cnt_tc = 0; 363 364 /* setup qos_info fields with defaults */ 365 qos_info->num_apps = 0; 366 qos_info->num_tc = 1; 367 368 for (j = 0; j < ICE_TC_MAX_USER_PRIORITY; j++) 369 qos_info->up2tc[j] = 0; 370 371 qos_info->tc_info[0].rel_bw = 100; 372 for (j = 1; j < IEEE_8021QAZ_MAX_TCS; j++) 373 qos_info->tc_info[j].rel_bw = 0; 374 375 /* gather current values */ 376 up2tc = rd32(hw, PRTDCB_TUP2TC); 377 qos_info->num_apps = dcbx_cfg->numapps; 378 379 for (j = 0; j < ICE_MAX_TRAFFIC_CLASS; j++) { 380 num_tc |= BIT(dcbx_cfg->etscfg.prio_table[j]); 381 } 382 for (j = 0; j < ICE_MAX_TRAFFIC_CLASS; j++) { 383 if (num_tc & BIT(j)) { 384 cnt_tc++; 385 val_tc |= BIT(j); 386 } else { 387 break; 388 } 389 } 390 qos_info->num_tc = (val_tc == num_tc && num_tc != 0) ? cnt_tc : 1; 391 for (j = 0; j < ICE_TC_MAX_USER_PRIORITY; j++) 392 qos_info->up2tc[j] = (up2tc >> (j * 3)) & 0x7; 393 394 for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) 395 qos_info->tc_info[j].rel_bw = dcbx_cfg->etscfg.tcbwtable[j]; 396 for (j = 0; j < qos_info->num_apps; j++) { 397 qos_info->apps[j].priority = dcbx_cfg->app[j].priority; 398 qos_info->apps[j].prot_id = dcbx_cfg->app[j].prot_id; 399 qos_info->apps[j].selector = dcbx_cfg->app[j].selector; 400 } 401 402 /* Gather DSCP-to-TC mapping and QoS/PFC mode */ 403 memcpy(qos_info->dscp_map, dcbx_cfg->dscp_map, sizeof(qos_info->dscp_map)); 404 qos_info->pfc_mode = dcbx_cfg->pfc_mode; 405 } 406 407 /** 408 * ice_rdma_check_version - Check that the provided RDMA version is compatible 409 * @info: the RDMA client information structure 410 * 411 * Verify that the client RDMA driver provided a version that is compatible 412 * with the driver interface. 413 */ 414 static int 415 ice_rdma_check_version(struct ice_rdma_info *info) 416 { 417 /* Make sure the MAJOR version matches */ 418 if (info->major_version != ICE_RDMA_MAJOR_VERSION) { 419 log(LOG_WARNING, "%s: the iRDMA driver requested version %d.%d.%d, but this driver only supports major version %d.x.x\n", 420 __func__, 421 info->major_version, info->minor_version, info->patch_version, 422 ICE_RDMA_MAJOR_VERSION); 423 return (ENOTSUP); 424 } 425 426 /* 427 * Make sure that the MINOR version is compatible. 428 * 429 * This means that the RDMA client driver version MUST not be greater 430 * than the version provided by the driver, as it would indicate that 431 * the RDMA client expects features which are not supported by the 432 * main driver. 433 */ 434 if (info->minor_version > ICE_RDMA_MINOR_VERSION) { 435 log(LOG_WARNING, "%s: the iRDMA driver requested version %d.%d.%d, but this driver only supports up to minor version %d.%d.x\n", 436 __func__, 437 info->major_version, info->minor_version, info->patch_version, 438 ICE_RDMA_MAJOR_VERSION, ICE_RDMA_MINOR_VERSION); 439 return (ENOTSUP); 440 } 441 442 /* 443 * Make sure that the PATCH version is compatible. 444 * 445 * This means that the RDMA client version MUST not be greater than 446 * the version provided by the driver, as it may indicate that the 447 * RDMA client expects certain backwards compatible bug fixes which 448 * are not implemented by this version of the main driver. 449 */ 450 if ((info->minor_version == ICE_RDMA_MINOR_VERSION) && 451 (info->patch_version > ICE_RDMA_PATCH_VERSION)) { 452 log(LOG_WARNING, "%s: the iRDMA driver requested version %d.%d.%d, but this driver only supports up to patch version %d.%d.%d\n", 453 __func__, 454 info->major_version, info->minor_version, info->patch_version, 455 ICE_RDMA_MAJOR_VERSION, ICE_RDMA_MINOR_VERSION, ICE_RDMA_PATCH_VERSION); 456 return (ENOTSUP); 457 } 458 459 /* Make sure that the kobject class is initialized */ 460 if (info->rdma_class == NULL) { 461 log(LOG_WARNING, "%s: the iRDMA driver did not specify a kobject interface\n", 462 __func__); 463 return (EINVAL); 464 } 465 466 return (0); 467 } 468 469 /** 470 * ice_rdma_register - Register an RDMA client driver 471 * @info: the RDMA client information structure 472 * 473 * Called by the RDMA client driver on load. Used to initialize the RDMA 474 * client driver interface and enable interop between the ice driver and the 475 * RDMA client driver. 476 * 477 * The RDMA client driver must provide the version number it expects, along 478 * with a pointer to a kobject class that extends the irdma_di_if class, and 479 * implements the irdma_if class interface. 480 */ 481 int 482 ice_rdma_register(struct ice_rdma_info *info) 483 { 484 struct ice_rdma_entry *entry; 485 struct ice_softc *sc; 486 int err = 0; 487 488 sx_xlock(&ice_rdma.mtx); 489 490 if (!ice_enable_irdma) { 491 log(LOG_INFO, "%s: The iRDMA driver interface has been disabled\n", __func__); 492 err = (ECONNREFUSED); 493 goto return_unlock; 494 } 495 496 if (ice_rdma.registered) { 497 log(LOG_WARNING, "%s: iRDMA driver already registered\n", __func__); 498 err = (EBUSY); 499 goto return_unlock; 500 } 501 502 /* Make sure the iRDMA version is compatible */ 503 err = ice_rdma_check_version(info); 504 if (err) 505 goto return_unlock; 506 507 log(LOG_INFO, "%s: iRDMA driver registered using version %d.%d.%d\n", 508 __func__, info->major_version, info->minor_version, info->patch_version); 509 510 ice_rdma.peer_class = info->rdma_class; 511 512 /* 513 * Initialize the kobject interface and notify the RDMA client of each 514 * existing PF interface. 515 */ 516 LIST_FOREACH(entry, &ice_rdma.peers, node) { 517 kobj_init((kobj_t)&entry->peer, ice_rdma.peer_class); 518 /* Gather DCB/QOS info into peer */ 519 sc = __containerof(entry, struct ice_softc, rdma_entry); 520 memset(&entry->peer.initial_qos_info, 0, sizeof(entry->peer.initial_qos_info)); 521 ice_rdma_cp_qos_info(&sc->hw, &sc->hw.port_info->qos_cfg.local_dcbx_cfg, 522 &entry->peer.initial_qos_info); 523 524 IRDMA_PROBE(&entry->peer); 525 if (entry->initiated) 526 IRDMA_OPEN(&entry->peer); 527 } 528 ice_rdma.registered = true; 529 530 return_unlock: 531 sx_xunlock(&ice_rdma.mtx); 532 533 return (err); 534 } 535 536 /** 537 * ice_rdma_unregister - Unregister an RDMA client driver 538 * 539 * Called by the RDMA client driver on unload. Used to de-initialize the RDMA 540 * client driver interface and shut down communication between the ice driver 541 * and the RDMA client driver. 542 */ 543 int 544 ice_rdma_unregister(void) 545 { 546 struct ice_rdma_entry *entry; 547 548 sx_xlock(&ice_rdma.mtx); 549 550 if (!ice_rdma.registered) { 551 log(LOG_WARNING, "%s: iRDMA driver was not previously registered\n", 552 __func__); 553 sx_xunlock(&ice_rdma.mtx); 554 return (ENOENT); 555 } 556 557 log(LOG_INFO, "%s: iRDMA driver unregistered\n", __func__); 558 ice_rdma.registered = false; 559 ice_rdma.peer_class = NULL; 560 561 /* 562 * Release the kobject interface for each of the existing PF 563 * interfaces. Note that we do not notify the client about removing 564 * each PF, as it is assumed that the client will have already cleaned 565 * up any associated resources when it is unregistered. 566 */ 567 LIST_FOREACH(entry, &ice_rdma.peers, node) 568 kobj_delete((kobj_t)&entry->peer, NULL); 569 570 sx_xunlock(&ice_rdma.mtx); 571 572 return (0); 573 } 574 575 /** 576 * ice_rdma_init - RDMA driver init routine 577 * 578 * Called during ice driver module initialization to setup the RDMA client 579 * interface mutex and RDMA peer structure list. 580 */ 581 void 582 ice_rdma_init(void) 583 { 584 LIST_INIT(&ice_rdma.peers); 585 sx_init_flags(&ice_rdma.mtx, "ice rdma interface", SX_DUPOK); 586 587 ice_rdma.registered = false; 588 ice_rdma.peer_class = NULL; 589 } 590 591 /** 592 * ice_rdma_exit - RDMA driver exit routine 593 * 594 * Called during ice driver module exit to shutdown the RDMA client interface 595 * mutex. 596 */ 597 void 598 ice_rdma_exit(void) 599 { 600 MPASS(LIST_EMPTY(&ice_rdma.peers)); 601 sx_destroy(&ice_rdma.mtx); 602 } 603 604 /** 605 * ice_rdma_pf_attach_locked - Prepare a PF for RDMA connections 606 * @sc: the ice driver softc 607 * 608 * Initialize a peer entry for this PF and add it to the RDMA interface list. 609 * Notify the client RDMA driver of a new PF device. 610 * 611 * @pre must be called while holding the ice_rdma mutex. 612 */ 613 static int 614 ice_rdma_pf_attach_locked(struct ice_softc *sc) 615 { 616 struct ice_rdma_entry *entry; 617 618 /* Do not attach the PF unless RDMA is supported */ 619 if (!ice_is_bit_set(sc->feat_cap, ICE_FEATURE_RDMA)) 620 return (0); 621 622 entry = &sc->rdma_entry; 623 if (entry->attached) { 624 device_printf(sc->dev, "iRDMA peer entry already exists\n"); 625 return (EEXIST); 626 } 627 628 entry->attached = true; 629 entry->peer.dev = sc->dev; 630 entry->peer.ifp = sc->ifp; 631 entry->peer.pf_id = sc->hw.pf_id; 632 entry->peer.pci_mem = sc->bar0.res; 633 entry->peer.pf_vsi_num = ice_get_hw_vsi_num(&sc->hw, sc->pf_vsi.idx); 634 if (sc->rdma_imap && sc->rdma_imap[0] != ICE_INVALID_RES_IDX && 635 sc->irdma_vectors > 0) { 636 entry->peer.msix.base = sc->rdma_imap[0]; 637 entry->peer.msix.count = sc->irdma_vectors; 638 } 639 640 /* Gather DCB/QOS info into peer */ 641 memset(&entry->peer.initial_qos_info, 0, sizeof(entry->peer.initial_qos_info)); 642 ice_rdma_cp_qos_info(&sc->hw, &sc->hw.port_info->qos_cfg.local_dcbx_cfg, 643 &entry->peer.initial_qos_info); 644 645 /* 646 * If the RDMA client driver has already registered, initialize the 647 * kobject and notify the client of a new PF 648 */ 649 if (ice_rdma.registered) { 650 kobj_init((kobj_t)&entry->peer, ice_rdma.peer_class); 651 IRDMA_PROBE(&entry->peer); 652 } 653 654 LIST_INSERT_HEAD(&ice_rdma.peers, entry, node); 655 656 ice_set_bit(ICE_FEATURE_RDMA, sc->feat_en); 657 658 return (0); 659 } 660 661 /** 662 * ice_rdma_pf_attach - Notify the RDMA client of a new PF 663 * @sc: the ice driver softc 664 * 665 * Called during PF attach to notify the RDMA client of a new PF. 666 */ 667 int 668 ice_rdma_pf_attach(struct ice_softc *sc) 669 { 670 int err; 671 672 sx_xlock(&ice_rdma.mtx); 673 err = ice_rdma_pf_attach_locked(sc); 674 sx_xunlock(&ice_rdma.mtx); 675 676 return (err); 677 } 678 679 /** 680 * ice_rdma_pf_detach_locked - Notify the RDMA client on PF detach 681 * @sc: the ice driver softc 682 * 683 * Notify the RDMA peer client driver of removal of a PF, and release any 684 * RDMA-specific resources associated with that PF. Remove the PF from the 685 * list of available RDMA entries. 686 * 687 * @pre must be called while holding the ice_rdma mutex. 688 */ 689 static void 690 ice_rdma_pf_detach_locked(struct ice_softc *sc) 691 { 692 struct ice_rdma_entry *entry; 693 694 /* No need to detach the PF if RDMA is not enabled */ 695 if (!ice_is_bit_set(sc->feat_en, ICE_FEATURE_RDMA)) 696 return; 697 698 entry = &sc->rdma_entry; 699 if (!entry->attached) { 700 device_printf(sc->dev, "iRDMA peer entry was not attached\n"); 701 return; 702 } 703 704 /* 705 * If the RDMA client driver is registered, notify the client that 706 * a PF has been removed, and release the kobject reference. 707 */ 708 if (ice_rdma.registered) { 709 IRDMA_REMOVE(&entry->peer); 710 kobj_delete((kobj_t)&entry->peer, NULL); 711 } 712 713 LIST_REMOVE(entry, node); 714 entry->attached = false; 715 716 ice_clear_bit(ICE_FEATURE_RDMA, sc->feat_en); 717 } 718 719 /** 720 * ice_rdma_pf_detach - Notify the RDMA client of a PF detaching 721 * @sc: the ice driver softc 722 * 723 * Take the ice_rdma mutex and then notify the RDMA client that a PF has been 724 * removed. 725 */ 726 void 727 ice_rdma_pf_detach(struct ice_softc *sc) 728 { 729 sx_xlock(&ice_rdma.mtx); 730 ice_rdma_pf_detach_locked(sc); 731 sx_xunlock(&ice_rdma.mtx); 732 } 733 734 /** 735 * ice_rdma_pf_init - Notify the RDMA client that a PF has initialized 736 * @sc: the ice driver softc 737 * 738 * Called by the ice driver when a PF has been initialized. Notifies the RDMA 739 * client that a PF is up and ready to operate. 740 */ 741 int 742 ice_rdma_pf_init(struct ice_softc *sc) 743 { 744 struct ice_rdma_peer *peer = &sc->rdma_entry.peer; 745 746 sx_xlock(&ice_rdma.mtx); 747 748 /* Update the MTU */ 749 peer->mtu = if_getmtu(sc->ifp); 750 sc->rdma_entry.initiated = true; 751 752 if (sc->rdma_entry.attached && ice_rdma.registered) { 753 sx_xunlock(&ice_rdma.mtx); 754 return IRDMA_OPEN(peer); 755 } 756 757 sx_xunlock(&ice_rdma.mtx); 758 759 return (0); 760 } 761 762 /** 763 * ice_rdma_pf_stop - Notify the RDMA client of a stopped PF device 764 * @sc: the ice driver softc 765 * 766 * Called by the ice driver when a PF is stopped. Notifies the RDMA client 767 * driver that the PF has stopped and is not ready to operate. 768 */ 769 int 770 ice_rdma_pf_stop(struct ice_softc *sc) 771 { 772 sx_xlock(&ice_rdma.mtx); 773 774 sc->rdma_entry.initiated = false; 775 if (sc->rdma_entry.attached && ice_rdma.registered) { 776 sx_xunlock(&ice_rdma.mtx); 777 return IRDMA_CLOSE(&sc->rdma_entry.peer); 778 } 779 780 sx_xunlock(&ice_rdma.mtx); 781 782 return (0); 783 } 784 785 /** 786 * ice_rdma_link_change - Notify RDMA client of a change in link status 787 * @sc: the ice driver softc 788 * @linkstate: the link status 789 * @baudrate: the link rate in bits per second 790 * 791 * Notify the RDMA client of a link status change, by sending it the new link 792 * state and baudrate. 793 * 794 * The link state is represented the same was as in the ifnet structure. It 795 * should be LINK_STATE_UNKNOWN, LINK_STATE_DOWN, or LINK_STATE_UP. 796 */ 797 void 798 ice_rdma_link_change(struct ice_softc *sc, int linkstate, uint64_t baudrate) 799 { 800 struct ice_rdma_peer *peer = &sc->rdma_entry.peer; 801 struct ice_rdma_event event; 802 803 memset(&event, 0, sizeof(struct ice_rdma_event)); 804 event.type = ICE_RDMA_EVENT_LINK_CHANGE; 805 event.linkstate = linkstate; 806 event.baudrate = baudrate; 807 808 sx_xlock(&ice_rdma.mtx); 809 810 if (sc->rdma_entry.attached && ice_rdma.registered) 811 IRDMA_EVENT_HANDLER(peer, &event); 812 813 sx_xunlock(&ice_rdma.mtx); 814 } 815 816 /** 817 * ice_rdma_notify_dcb_qos_change - notify RDMA driver to pause traffic 818 * @sc: the ice driver softc 819 * 820 * Notify the RDMA driver that QOS/DCB settings are about to change. 821 * Once the function return, all the QPs should be suspended. 822 */ 823 void 824 ice_rdma_notify_dcb_qos_change(struct ice_softc *sc) 825 { 826 struct ice_rdma_peer *peer = &sc->rdma_entry.peer; 827 struct ice_rdma_event event; 828 829 memset(&event, 0, sizeof(struct ice_rdma_event)); 830 event.type = ICE_RDMA_EVENT_TC_CHANGE; 831 /* pre-event */ 832 event.prep = true; 833 834 sx_xlock(&ice_rdma.mtx); 835 if (sc->rdma_entry.attached && ice_rdma.registered) 836 IRDMA_EVENT_HANDLER(peer, &event); 837 sx_xunlock(&ice_rdma.mtx); 838 } 839 840 /** 841 * ice_rdma_dcb_qos_update - pass the changed dcb settings to RDMA driver 842 * @sc: the ice driver softc 843 * @pi: the port info structure 844 * 845 * Pass the changed DCB settings to RDMA traffic. This function should be 846 * called only after ice_rdma_notify_dcb_qos_change has been called and 847 * returned before. After the function returns, all the RDMA traffic 848 * should be resumed. 849 */ 850 void 851 ice_rdma_dcb_qos_update(struct ice_softc *sc, struct ice_port_info *pi) 852 { 853 struct ice_rdma_peer *peer = &sc->rdma_entry.peer; 854 struct ice_rdma_event event; 855 856 memset(&event, 0, sizeof(struct ice_rdma_event)); 857 event.type = ICE_RDMA_EVENT_TC_CHANGE; 858 /* post-event */ 859 event.prep = false; 860 861 /* gather current configuration */ 862 ice_rdma_cp_qos_info(&sc->hw, &pi->qos_cfg.local_dcbx_cfg, &event.port_qos); 863 sx_xlock(&ice_rdma.mtx); 864 if (sc->rdma_entry.attached && ice_rdma.registered) 865 IRDMA_EVENT_HANDLER(peer, &event); 866 sx_xunlock(&ice_rdma.mtx); 867 } 868 869 /** 870 * ice_rdma_notify_pe_intr - notify irdma on incoming interrupts regarding PE 871 * @sc: the ice driver softc 872 * @oicr: interrupt cause 873 * 874 * Pass the information about received interrupt to RDMA driver if it was 875 * relating to PE. Specifically PE_CRITERR and HMC_ERR. 876 * The irdma driver shall decide what should be done upon these interrupts. 877 */ 878 void 879 ice_rdma_notify_pe_intr(struct ice_softc *sc, uint32_t oicr) 880 { 881 struct ice_rdma_peer *peer = &sc->rdma_entry.peer; 882 struct ice_rdma_event event; 883 884 memset(&event, 0, sizeof(struct ice_rdma_event)); 885 event.type = ICE_RDMA_EVENT_CRIT_ERR; 886 event.oicr_reg = oicr; 887 888 sx_xlock(&ice_rdma.mtx); 889 if (sc->rdma_entry.attached && ice_rdma.registered) 890 IRDMA_EVENT_HANDLER(peer, &event); 891 sx_xunlock(&ice_rdma.mtx); 892 } 893 894 /** 895 * ice_rdma_notify_reset - notify irdma on incoming pf-reset 896 * @sc: the ice driver softc 897 * 898 * Inform irdma driver of an incoming PF reset. 899 * The irdma driver shall set its state to reset, and avoid using CQP 900 * anymore. Next step should be to call ice_rdma_pf_stop in order to 901 * remove resources. 902 */ 903 void 904 ice_rdma_notify_reset(struct ice_softc *sc) 905 { 906 struct ice_rdma_peer *peer = &sc->rdma_entry.peer; 907 struct ice_rdma_event event; 908 909 memset(&event, 0, sizeof(struct ice_rdma_event)); 910 event.type = ICE_RDMA_EVENT_RESET; 911 912 sx_xlock(&ice_rdma.mtx); 913 if (sc->rdma_entry.attached && ice_rdma.registered) 914 IRDMA_EVENT_HANDLER(peer, &event); 915 sx_xunlock(&ice_rdma.mtx); 916 } 917