Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'aux-bus-v11' of https://github.com/ajitkhaparde1/linux

Ajit Khaparde says:

====================
bnxt: Add Auxiliary driver support

Add auxiliary device driver for Broadcom devices.
The bnxt_en driver will register and initialize an aux device
if RDMA is enabled in the underlying device.
The bnxt_re driver will then probe and initialize the
RoCE interfaces with the infiniband stack.

We got rid of the bnxt_en_ops which the bnxt_re driver used to
communicate with bnxt_en.
Similarly We have tried to clean up most of the bnxt_ulp_ops.
In most of the cases we used the functions and entry points provided
by the auxiliary bus driver framework.
And now these are the minimal functions needed to support the functionality.

We will try to work on getting rid of the remaining if we find any
other viable option in future.

* 'aux-bus-v11' of https://github.com/ajitkhaparde1/linux:
bnxt_en: Remove runtime interrupt vector allocation
RDMA/bnxt_re: Remove the sriov config callback
bnxt_en: Remove struct bnxt access from RoCE driver
bnxt_en: Use auxiliary bus calls over proprietary calls
bnxt_en: Use direct API instead of indirection
bnxt_en: Remove usage of ulp_id
RDMA/bnxt_re: Use auxiliary driver interface
bnxt_en: Add auxiliary driver support
====================

Link: https://lore.kernel.org/r/20230202033809.3989-1-ajit.khaparde@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+478 -752
+1 -9
drivers/infiniband/hw/bnxt_re/bnxt_re.h
··· 89 89 u8 mode; 90 90 }; 91 91 92 - struct bnxt_re_work { 93 - struct work_struct work; 94 - unsigned long event; 95 - struct bnxt_re_dev *rdev; 96 - struct net_device *vlan_dev; 97 - }; 98 - 99 92 struct bnxt_re_sqp_entries { 100 93 struct bnxt_qplib_sge sge; 101 94 u64 wrid; ··· 125 132 #define BNXT_RE_FLAG_ERR_DEVICE_DETACHED 17 126 133 #define BNXT_RE_FLAG_ISSUE_ROCE_STATS 29 127 134 struct net_device *netdev; 135 + struct notifier_block nb; 128 136 unsigned int version, major, minor; 129 137 struct bnxt_qplib_chip_ctx *chip_ctx; 130 138 struct bnxt_en_dev *en_dev; 131 - struct bnxt_msix_entry msix_entries[BNXT_RE_MAX_MSIX]; 132 139 int num_msix; 133 140 134 141 int id; ··· 187 194 return &rdev->ibdev.dev; 188 195 return NULL; 189 196 } 190 - 191 197 #endif
+233 -418
drivers/infiniband/hw/bnxt_re/main.c
··· 48 48 #include <net/ipv6.h> 49 49 #include <net/addrconf.h> 50 50 #include <linux/if_ether.h> 51 + #include <linux/auxiliary_bus.h> 51 52 52 53 #include <rdma/ib_verbs.h> 53 54 #include <rdma/ib_user_verbs.h> ··· 75 74 MODULE_LICENSE("Dual BSD/GPL"); 76 75 77 76 /* globals */ 78 - static struct list_head bnxt_re_dev_list = LIST_HEAD_INIT(bnxt_re_dev_list); 79 - /* Mutex to protect the list of bnxt_re devices added */ 80 - static DEFINE_MUTEX(bnxt_re_dev_lock); 81 - static struct workqueue_struct *bnxt_re_wq; 82 - static void bnxt_re_remove_device(struct bnxt_re_dev *rdev); 83 - static void bnxt_re_dealloc_driver(struct ib_device *ib_dev); 77 + static DEFINE_MUTEX(bnxt_re_mutex); 78 + 84 79 static void bnxt_re_stop_irq(void *handle); 85 80 static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev); 81 + static int bnxt_re_netdev_event(struct notifier_block *notifier, 82 + unsigned long event, void *ptr); 83 + static struct bnxt_re_dev *bnxt_re_from_netdev(struct net_device *netdev); 84 + static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev); 86 85 87 86 static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev, u8 mode) 88 87 { ··· 112 111 { 113 112 struct bnxt_qplib_chip_ctx *chip_ctx; 114 113 struct bnxt_en_dev *en_dev; 115 - struct bnxt *bp; 116 114 117 115 en_dev = rdev->en_dev; 118 - bp = netdev_priv(en_dev->net); 119 116 120 117 chip_ctx = kzalloc(sizeof(*chip_ctx), GFP_KERNEL); 121 118 if (!chip_ctx) 122 119 return -ENOMEM; 123 - chip_ctx->chip_num = bp->chip_num; 124 - chip_ctx->hw_stats_size = bp->hw_ring_stats_size; 120 + chip_ctx->chip_num = en_dev->chip_num; 121 + chip_ctx->hw_stats_size = en_dev->hw_ring_stats_size; 125 122 126 123 rdev->chip_ctx = chip_ctx; 127 124 /* rest members to follow eventually */ ··· 127 128 rdev->qplib_res.cctx = rdev->chip_ctx; 128 129 rdev->rcfw.res = &rdev->qplib_res; 129 130 rdev->qplib_res.dattr = &rdev->dev_attr; 130 - rdev->qplib_res.is_vf = BNXT_VF(bp); 131 + rdev->qplib_res.is_vf = BNXT_EN_VF(en_dev); 131 132 132 133 bnxt_re_set_drv_mode(rdev, wqe_mode); 133 134 if (bnxt_qplib_determine_atomics(en_dev->pdev)) ··· 140 141 141 142 static void bnxt_re_get_sriov_func_type(struct bnxt_re_dev *rdev) 142 143 { 143 - struct bnxt *bp; 144 - 145 - bp = netdev_priv(rdev->en_dev->net); 146 - if (BNXT_VF(bp)) 144 + if (BNXT_EN_VF(rdev->en_dev)) 147 145 rdev->is_virtfn = 1; 148 146 } 149 147 ··· 221 225 bnxt_re_limit_vf_res(&rdev->qplib_ctx, num_vfs); 222 226 } 223 227 224 - /* for handling bnxt_en callbacks later */ 225 - static void bnxt_re_stop(void *p) 228 + static void bnxt_re_vf_res_config(struct bnxt_re_dev *rdev) 226 229 { 227 - struct bnxt_re_dev *rdev = p; 228 - struct bnxt *bp; 229 - 230 - if (!rdev) 231 - return; 232 - ASSERT_RTNL(); 233 - 234 - /* L2 driver invokes this callback during device error/crash or device 235 - * reset. Current RoCE driver doesn't recover the device in case of 236 - * error. Handle the error by dispatching fatal events to all qps 237 - * ie. by calling bnxt_re_dev_stop and release the MSIx vectors as 238 - * L2 driver want to modify the MSIx table. 239 - */ 240 - bp = netdev_priv(rdev->netdev); 241 - 242 - ibdev_info(&rdev->ibdev, "Handle device stop call from L2 driver"); 243 - /* Check the current device state from L2 structure and move the 244 - * device to detached state if FW_FATAL_COND is set. 245 - * This prevents more commands to HW during clean-up, 246 - * in case the device is already in error. 247 - */ 248 - if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state)) 249 - set_bit(ERR_DEVICE_DETACHED, &rdev->rcfw.cmdq.flags); 250 - 251 - bnxt_re_dev_stop(rdev); 252 - bnxt_re_stop_irq(rdev); 253 - /* Move the device states to detached and avoid sending any more 254 - * commands to HW 255 - */ 256 - set_bit(BNXT_RE_FLAG_ERR_DEVICE_DETACHED, &rdev->flags); 257 - set_bit(ERR_DEVICE_DETACHED, &rdev->rcfw.cmdq.flags); 258 - } 259 - 260 - static void bnxt_re_start(void *p) 261 - { 262 - } 263 - 264 - static void bnxt_re_sriov_config(void *p, int num_vfs) 265 - { 266 - struct bnxt_re_dev *rdev = p; 267 - 268 - if (!rdev) 269 - return; 270 230 271 231 if (test_bit(BNXT_RE_FLAG_ERR_DEVICE_DETACHED, &rdev->flags)) 272 232 return; 273 - rdev->num_vfs = num_vfs; 233 + rdev->num_vfs = pci_sriov_get_totalvfs(rdev->en_dev->pdev); 274 234 if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) { 275 235 bnxt_re_set_resource_limits(rdev); 276 236 bnxt_qplib_set_func_resources(&rdev->qplib_res, &rdev->rcfw, ··· 234 282 } 235 283 } 236 284 237 - static void bnxt_re_shutdown(void *p) 285 + static void bnxt_re_shutdown(struct auxiliary_device *adev) 238 286 { 239 - struct bnxt_re_dev *rdev = p; 287 + struct bnxt_re_dev *rdev = auxiliary_get_drvdata(adev); 240 288 241 289 if (!rdev) 242 290 return; 243 - ASSERT_RTNL(); 244 - /* Release the MSIx vectors before queuing unregister */ 245 - bnxt_re_stop_irq(rdev); 246 - ib_unregister_device_queued(&rdev->ibdev); 291 + ib_unregister_device(&rdev->ibdev); 292 + bnxt_re_dev_uninit(rdev); 247 293 } 248 294 249 295 static void bnxt_re_stop_irq(void *handle) ··· 262 312 static void bnxt_re_start_irq(void *handle, struct bnxt_msix_entry *ent) 263 313 { 264 314 struct bnxt_re_dev *rdev = (struct bnxt_re_dev *)handle; 265 - struct bnxt_msix_entry *msix_ent = rdev->msix_entries; 315 + struct bnxt_msix_entry *msix_ent = rdev->en_dev->msix_entries; 266 316 struct bnxt_qplib_rcfw *rcfw = &rdev->rcfw; 267 317 struct bnxt_qplib_nq *nq; 268 318 int indx, rc; ··· 281 331 * in device sctructure. 282 332 */ 283 333 for (indx = 0; indx < rdev->num_msix; indx++) 284 - rdev->msix_entries[indx].vector = ent[indx].vector; 334 + rdev->en_dev->msix_entries[indx].vector = ent[indx].vector; 285 335 286 336 bnxt_qplib_rcfw_start_irq(rcfw, msix_ent[BNXT_RE_AEQ_IDX].vector, 287 337 false); ··· 296 346 } 297 347 298 348 static struct bnxt_ulp_ops bnxt_re_ulp_ops = { 299 - .ulp_async_notifier = NULL, 300 - .ulp_stop = bnxt_re_stop, 301 - .ulp_start = bnxt_re_start, 302 - .ulp_sriov_config = bnxt_re_sriov_config, 303 - .ulp_shutdown = bnxt_re_shutdown, 304 349 .ulp_irq_stop = bnxt_re_stop_irq, 305 350 .ulp_irq_restart = bnxt_re_start_irq 306 351 }; 307 352 308 353 /* RoCE -> Net driver */ 309 354 310 - /* Driver registration routines used to let the networking driver (bnxt_en) 311 - * to know that the RoCE driver is now installed 312 - */ 313 - static int bnxt_re_unregister_netdev(struct bnxt_re_dev *rdev) 314 - { 315 - struct bnxt_en_dev *en_dev; 316 - int rc; 317 - 318 - if (!rdev) 319 - return -EINVAL; 320 - 321 - en_dev = rdev->en_dev; 322 - 323 - rc = en_dev->en_ops->bnxt_unregister_device(rdev->en_dev, 324 - BNXT_ROCE_ULP); 325 - return rc; 326 - } 327 - 328 355 static int bnxt_re_register_netdev(struct bnxt_re_dev *rdev) 329 356 { 330 357 struct bnxt_en_dev *en_dev; 331 358 int rc = 0; 332 359 333 - if (!rdev) 334 - return -EINVAL; 335 - 336 360 en_dev = rdev->en_dev; 337 361 338 - rc = en_dev->en_ops->bnxt_register_device(en_dev, BNXT_ROCE_ULP, 339 - &bnxt_re_ulp_ops, rdev); 340 - rdev->qplib_res.pdev = rdev->en_dev->pdev; 341 - return rc; 342 - } 343 - 344 - static int bnxt_re_free_msix(struct bnxt_re_dev *rdev) 345 - { 346 - struct bnxt_en_dev *en_dev; 347 - int rc; 348 - 349 - if (!rdev) 350 - return -EINVAL; 351 - 352 - en_dev = rdev->en_dev; 353 - 354 - 355 - rc = en_dev->en_ops->bnxt_free_msix(rdev->en_dev, BNXT_ROCE_ULP); 356 - 357 - return rc; 358 - } 359 - 360 - static int bnxt_re_request_msix(struct bnxt_re_dev *rdev) 361 - { 362 - int rc = 0, num_msix_want = BNXT_RE_MAX_MSIX, num_msix_got; 363 - struct bnxt_en_dev *en_dev; 364 - 365 - if (!rdev) 366 - return -EINVAL; 367 - 368 - en_dev = rdev->en_dev; 369 - 370 - num_msix_want = min_t(u32, BNXT_RE_MAX_MSIX, num_online_cpus()); 371 - 372 - num_msix_got = en_dev->en_ops->bnxt_request_msix(en_dev, BNXT_ROCE_ULP, 373 - rdev->msix_entries, 374 - num_msix_want); 375 - if (num_msix_got < BNXT_RE_MIN_MSIX) { 376 - rc = -EINVAL; 377 - goto done; 378 - } 379 - if (num_msix_got != num_msix_want) { 380 - ibdev_warn(&rdev->ibdev, 381 - "Requested %d MSI-X vectors, got %d\n", 382 - num_msix_want, num_msix_got); 383 - } 384 - rdev->num_msix = num_msix_got; 385 - done: 362 + rc = bnxt_register_dev(en_dev, &bnxt_re_ulp_ops, rdev); 363 + if (!rc) 364 + rdev->qplib_res.pdev = rdev->en_dev->pdev; 386 365 return rc; 387 366 } 388 367 ··· 337 458 static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, 338 459 u16 fw_ring_id, int type) 339 460 { 340 - struct bnxt_en_dev *en_dev = rdev->en_dev; 461 + struct bnxt_en_dev *en_dev; 341 462 struct hwrm_ring_free_input req = {0}; 342 463 struct hwrm_ring_free_output resp; 343 464 struct bnxt_fw_msg fw_msg; 344 465 int rc = -EINVAL; 466 + 467 + if (!rdev) 468 + return rc; 469 + 470 + en_dev = rdev->en_dev; 345 471 346 472 if (!en_dev) 347 473 return rc; ··· 361 477 req.ring_id = cpu_to_le16(fw_ring_id); 362 478 bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, 363 479 sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); 364 - rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); 480 + rc = bnxt_send_msg(en_dev, &fw_msg); 365 481 if (rc) 366 482 ibdev_err(&rdev->ibdev, "Failed to free HW ring:%d :%#x", 367 483 req.ring_id, rc); ··· 398 514 req.int_mode = ring_attr->mode; 399 515 bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, 400 516 sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); 401 - rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); 517 + rc = bnxt_send_msg(en_dev, &fw_msg); 402 518 if (!rc) 403 519 *fw_ring_id = le16_to_cpu(resp.ring_id); 404 520 ··· 426 542 req.stat_ctx_id = cpu_to_le32(fw_stats_ctx_id); 427 543 bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, 428 544 sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); 429 - rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); 545 + rc = bnxt_send_msg(en_dev, &fw_msg); 430 546 if (rc) 431 547 ibdev_err(&rdev->ibdev, "Failed to free HW stats context %#x", 432 548 rc); ··· 459 575 req.stat_ctx_flags = STAT_CTX_ALLOC_REQ_STAT_CTX_FLAGS_ROCE; 460 576 bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, 461 577 sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); 462 - rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); 578 + rc = bnxt_send_msg(en_dev, &fw_msg); 463 579 if (!rc) 464 580 *fw_stats_ctx_id = le32_to_cpu(resp.stat_ctx_id); 465 581 ··· 467 583 } 468 584 469 585 /* Device */ 470 - 471 - static bool is_bnxt_re_dev(struct net_device *netdev) 472 - { 473 - struct ethtool_drvinfo drvinfo; 474 - 475 - if (netdev->ethtool_ops && netdev->ethtool_ops->get_drvinfo) { 476 - memset(&drvinfo, 0, sizeof(drvinfo)); 477 - netdev->ethtool_ops->get_drvinfo(netdev, &drvinfo); 478 - 479 - if (strcmp(drvinfo.driver, "bnxt_en")) 480 - return false; 481 - return true; 482 - } 483 - return false; 484 - } 485 586 486 587 static struct bnxt_re_dev *bnxt_re_from_netdev(struct net_device *netdev) 487 588 { ··· 476 607 return NULL; 477 608 478 609 return container_of(ibdev, struct bnxt_re_dev, ibdev); 479 - } 480 - 481 - static struct bnxt_en_dev *bnxt_re_dev_probe(struct net_device *netdev) 482 - { 483 - struct bnxt_en_dev *en_dev; 484 - struct pci_dev *pdev; 485 - 486 - en_dev = bnxt_ulp_probe(netdev); 487 - if (IS_ERR(en_dev)) 488 - return en_dev; 489 - 490 - pdev = en_dev->pdev; 491 - if (!pdev) 492 - return ERR_PTR(-EINVAL); 493 - 494 - if (!(en_dev->flags & BNXT_EN_FLAG_ROCE_CAP)) { 495 - dev_info(&pdev->dev, 496 - "%s: probe error: RoCE is not supported on this device", 497 - ROCE_DRV_MODULE_NAME); 498 - return ERR_PTR(-ENODEV); 499 - } 500 - 501 - dev_hold(netdev); 502 - 503 - return en_dev; 504 610 } 505 611 506 612 static ssize_t hw_rev_show(struct device *device, struct device_attribute *attr, ··· 523 679 .create_qp = bnxt_re_create_qp, 524 680 .create_srq = bnxt_re_create_srq, 525 681 .create_user_ah = bnxt_re_create_ah, 526 - .dealloc_driver = bnxt_re_dealloc_driver, 527 682 .dealloc_pd = bnxt_re_dealloc_pd, 528 683 .dealloc_ucontext = bnxt_re_dealloc_ucontext, 529 684 .del_gid = bnxt_re_del_gid, ··· 587 744 return ib_register_device(ibdev, "bnxt_re%d", &rdev->en_dev->pdev->dev); 588 745 } 589 746 590 - static void bnxt_re_dev_remove(struct bnxt_re_dev *rdev) 591 - { 592 - dev_put(rdev->netdev); 593 - rdev->netdev = NULL; 594 - mutex_lock(&bnxt_re_dev_lock); 595 - list_del_rcu(&rdev->list); 596 - mutex_unlock(&bnxt_re_dev_lock); 597 - 598 - synchronize_rcu(); 599 - } 600 - 601 - static struct bnxt_re_dev *bnxt_re_dev_add(struct net_device *netdev, 747 + static struct bnxt_re_dev *bnxt_re_dev_add(struct bnxt_aux_priv *aux_priv, 602 748 struct bnxt_en_dev *en_dev) 603 749 { 604 750 struct bnxt_re_dev *rdev; ··· 600 768 return NULL; 601 769 } 602 770 /* Default values */ 603 - rdev->netdev = netdev; 604 - dev_hold(rdev->netdev); 771 + rdev->nb.notifier_call = NULL; 772 + rdev->netdev = en_dev->net; 605 773 rdev->en_dev = en_dev; 606 774 rdev->id = rdev->en_dev->pdev->devfn; 607 775 INIT_LIST_HEAD(&rdev->qp_list); ··· 616 784 rdev->cosq[0] = 0xFFFF; 617 785 rdev->cosq[1] = 0xFFFF; 618 786 619 - mutex_lock(&bnxt_re_dev_lock); 620 - list_add_tail_rcu(&rdev->list, &bnxt_re_dev_list); 621 - mutex_unlock(&bnxt_re_dev_lock); 622 787 return rdev; 623 788 } 624 789 ··· 759 930 return bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ? 760 931 (rdev->is_virtfn ? BNXT_RE_GEN_P5_VF_NQ_DB : 761 932 BNXT_RE_GEN_P5_PF_NQ_DB) : 762 - rdev->msix_entries[indx].db_offset; 933 + rdev->en_dev->msix_entries[indx].db_offset; 763 934 } 764 935 765 936 static void bnxt_re_cleanup_res(struct bnxt_re_dev *rdev) ··· 784 955 for (i = 1; i < rdev->num_msix ; i++) { 785 956 db_offt = bnxt_re_get_nqdb_offset(rdev, i); 786 957 rc = bnxt_qplib_enable_nq(rdev->en_dev->pdev, &rdev->nq[i - 1], 787 - i - 1, rdev->msix_entries[i].vector, 958 + i - 1, rdev->en_dev->msix_entries[i].vector, 788 959 db_offt, &bnxt_re_cqn_handler, 789 960 &bnxt_re_srqn_handler); 790 961 if (rc) { ··· 871 1042 rattr.type = type; 872 1043 rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX; 873 1044 rattr.depth = BNXT_QPLIB_NQE_MAX_CNT - 1; 874 - rattr.lrid = rdev->msix_entries[i + 1].ring_idx; 1045 + rattr.lrid = rdev->en_dev->msix_entries[i + 1].ring_idx; 875 1046 rc = bnxt_re_net_ring_alloc(rdev, &rattr, &nq->ring_id); 876 1047 if (rc) { 877 1048 ibdev_err(&rdev->ibdev, ··· 924 1095 u64 *cid_map) 925 1096 { 926 1097 struct hwrm_queue_pri2cos_qcfg_input req = {0}; 927 - struct bnxt *bp = netdev_priv(rdev->netdev); 928 1098 struct hwrm_queue_pri2cos_qcfg_output resp; 929 1099 struct bnxt_en_dev *en_dev = rdev->en_dev; 930 1100 struct bnxt_fw_msg fw_msg; ··· 940 1112 flags |= (dir & 0x01); 941 1113 flags |= HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_IVLAN; 942 1114 req.flags = cpu_to_le32(flags); 943 - req.port_id = bp->pf.port_id; 1115 + req.port_id = en_dev->pf_port_id; 944 1116 945 1117 bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, 946 1118 sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); 947 - rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); 1119 + rc = bnxt_send_msg(en_dev, &fw_msg); 948 1120 if (rc) 949 1121 return rc; 950 1122 ··· 1127 1299 req.hwrm_intf_upd = HWRM_VERSION_UPDATE; 1128 1300 bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, 1129 1301 sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); 1130 - rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg); 1302 + rc = bnxt_send_msg(en_dev, &fw_msg); 1131 1303 if (rc) { 1132 1304 ibdev_err(&rdev->ibdev, "Failed to query HW version, rc = 0x%x", 1133 1305 rc); ··· 1151 1323 pr_err("Failed to register with IB: %#x\n", rc); 1152 1324 return rc; 1153 1325 } 1154 - dev_info(rdev_to_dev(rdev), "Device registered successfully"); 1326 + dev_info(rdev_to_dev(rdev), "Device registered with IB successfully"); 1155 1327 ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, 1156 1328 &rdev->active_width); 1157 1329 set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags); ··· 1190 1362 bnxt_re_net_ring_free(rdev, rdev->rcfw.creq.ring_id, type); 1191 1363 bnxt_qplib_free_rcfw_channel(&rdev->rcfw); 1192 1364 } 1193 - if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) { 1194 - rc = bnxt_re_free_msix(rdev); 1195 - if (rc) 1196 - ibdev_warn(&rdev->ibdev, 1197 - "Failed to free MSI-X vectors: %#x", rc); 1198 - } 1365 + if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) 1366 + rdev->num_msix = 0; 1199 1367 1200 1368 bnxt_re_destroy_chip_ctx(rdev); 1201 - if (test_and_clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags)) { 1202 - rc = bnxt_re_unregister_netdev(rdev); 1203 - if (rc) 1204 - ibdev_warn(&rdev->ibdev, 1205 - "Failed to unregister with netdev: %#x", rc); 1206 - } 1369 + if (test_and_clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags)) 1370 + bnxt_unregister_dev(rdev->en_dev); 1207 1371 } 1208 1372 1209 1373 /* worker thread for polling periodic events. Now used for QoS programming*/ ··· 1236 1416 /* Check whether VF or PF */ 1237 1417 bnxt_re_get_sriov_func_type(rdev); 1238 1418 1239 - rc = bnxt_re_request_msix(rdev); 1240 - if (rc) { 1419 + if (!rdev->en_dev->ulp_tbl->msix_requested) { 1241 1420 ibdev_err(&rdev->ibdev, 1242 1421 "Failed to get MSI-X vectors: %#x\n", rc); 1243 1422 rc = -EINVAL; 1244 1423 goto fail; 1245 1424 } 1425 + ibdev_dbg(&rdev->ibdev, "Got %d MSI-X vectors\n", 1426 + rdev->en_dev->ulp_tbl->msix_requested); 1427 + rdev->num_msix = rdev->en_dev->ulp_tbl->msix_requested; 1246 1428 set_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags); 1247 1429 1248 1430 bnxt_re_query_hwrm_intf_version(rdev); ··· 1268 1446 rattr.type = type; 1269 1447 rattr.mode = RING_ALLOC_REQ_INT_MODE_MSIX; 1270 1448 rattr.depth = BNXT_QPLIB_CREQE_MAX_CNT - 1; 1271 - rattr.lrid = rdev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx; 1449 + rattr.lrid = rdev->en_dev->msix_entries[BNXT_RE_AEQ_IDX].ring_idx; 1272 1450 rc = bnxt_re_net_ring_alloc(rdev, &rattr, &creq->ring_id); 1273 1451 if (rc) { 1274 1452 ibdev_err(&rdev->ibdev, "Failed to allocate CREQ: %#x\n", rc); 1275 1453 goto free_rcfw; 1276 1454 } 1277 1455 db_offt = bnxt_re_get_nqdb_offset(rdev, BNXT_RE_AEQ_IDX); 1278 - vid = rdev->msix_entries[BNXT_RE_AEQ_IDX].vector; 1456 + vid = rdev->en_dev->msix_entries[BNXT_RE_AEQ_IDX].vector; 1279 1457 rc = bnxt_qplib_enable_rcfw_channel(&rdev->rcfw, 1280 1458 vid, db_offt, rdev->is_virtfn, 1281 1459 &bnxt_re_aeq_handler); ··· 1343 1521 INIT_DELAYED_WORK(&rdev->worker, bnxt_re_worker); 1344 1522 set_bit(BNXT_RE_FLAG_QOS_WORK_REG, &rdev->flags); 1345 1523 schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000)); 1524 + /* 1525 + * Use the total VF count since the actual VF count may not be 1526 + * available at this point. 1527 + */ 1528 + bnxt_re_vf_res_config(rdev); 1346 1529 } 1347 1530 1348 1531 return 0; ··· 1368 1541 return rc; 1369 1542 } 1370 1543 1371 - static void bnxt_re_dev_unreg(struct bnxt_re_dev *rdev) 1544 + static int bnxt_re_add_device(struct auxiliary_device *adev, u8 wqe_mode) 1372 1545 { 1373 - struct net_device *netdev = rdev->netdev; 1374 - 1375 - bnxt_re_dev_remove(rdev); 1376 - 1377 - if (netdev) 1378 - dev_put(netdev); 1379 - } 1380 - 1381 - static int bnxt_re_dev_reg(struct bnxt_re_dev **rdev, struct net_device *netdev) 1382 - { 1546 + struct bnxt_aux_priv *aux_priv = 1547 + container_of(adev, struct bnxt_aux_priv, aux_dev); 1383 1548 struct bnxt_en_dev *en_dev; 1384 - int rc = 0; 1385 - 1386 - if (!is_bnxt_re_dev(netdev)) 1387 - return -ENODEV; 1388 - 1389 - en_dev = bnxt_re_dev_probe(netdev); 1390 - if (IS_ERR(en_dev)) { 1391 - if (en_dev != ERR_PTR(-ENODEV)) 1392 - ibdev_err(&(*rdev)->ibdev, "%s: Failed to probe\n", 1393 - ROCE_DRV_MODULE_NAME); 1394 - rc = PTR_ERR(en_dev); 1395 - goto exit; 1396 - } 1397 - *rdev = bnxt_re_dev_add(netdev, en_dev); 1398 - if (!*rdev) { 1399 - rc = -ENOMEM; 1400 - dev_put(netdev); 1401 - goto exit; 1402 - } 1403 - exit: 1404 - return rc; 1405 - } 1406 - 1407 - static void bnxt_re_remove_device(struct bnxt_re_dev *rdev) 1408 - { 1409 - bnxt_re_dev_uninit(rdev); 1410 - pci_dev_put(rdev->en_dev->pdev); 1411 - bnxt_re_dev_unreg(rdev); 1412 - } 1413 - 1414 - static int bnxt_re_add_device(struct bnxt_re_dev **rdev, 1415 - struct net_device *netdev, u8 wqe_mode) 1416 - { 1417 - int rc; 1418 - 1419 - rc = bnxt_re_dev_reg(rdev, netdev); 1420 - if (rc == -ENODEV) 1421 - return rc; 1422 - if (rc) { 1423 - pr_err("Failed to register with the device %s: %#x\n", 1424 - netdev->name, rc); 1425 - return rc; 1426 - } 1427 - 1428 - pci_dev_get((*rdev)->en_dev->pdev); 1429 - rc = bnxt_re_dev_init(*rdev, wqe_mode); 1430 - if (rc) { 1431 - pci_dev_put((*rdev)->en_dev->pdev); 1432 - bnxt_re_dev_unreg(*rdev); 1433 - } 1434 - 1435 - return rc; 1436 - } 1437 - 1438 - static void bnxt_re_dealloc_driver(struct ib_device *ib_dev) 1439 - { 1440 - struct bnxt_re_dev *rdev = 1441 - container_of(ib_dev, struct bnxt_re_dev, ibdev); 1442 - 1443 - dev_info(rdev_to_dev(rdev), "Unregistering Device"); 1444 - 1445 - rtnl_lock(); 1446 - bnxt_re_remove_device(rdev); 1447 - rtnl_unlock(); 1448 - } 1449 - 1450 - /* Handle all deferred netevents tasks */ 1451 - static void bnxt_re_task(struct work_struct *work) 1452 - { 1453 - struct bnxt_re_work *re_work; 1454 1549 struct bnxt_re_dev *rdev; 1455 1550 int rc = 0; 1456 1551 1457 - re_work = container_of(work, struct bnxt_re_work, work); 1458 - rdev = re_work->rdev; 1552 + /* en_dev should never be NULL as long as adev and aux_dev are valid. */ 1553 + en_dev = aux_priv->edev; 1459 1554 1460 - if (re_work->event == NETDEV_REGISTER) { 1461 - rc = bnxt_re_ib_init(rdev); 1462 - if (rc) { 1463 - ibdev_err(&rdev->ibdev, 1464 - "Failed to register with IB: %#x", rc); 1465 - rtnl_lock(); 1466 - bnxt_re_remove_device(rdev); 1467 - rtnl_unlock(); 1468 - goto exit; 1469 - } 1555 + rdev = bnxt_re_dev_add(aux_priv, en_dev); 1556 + if (!rdev || !rdev_to_dev(rdev)) { 1557 + rc = -ENOMEM; 1470 1558 goto exit; 1471 1559 } 1472 1560 1473 - if (!ib_device_try_get(&rdev->ibdev)) 1474 - goto exit; 1561 + rc = bnxt_re_dev_init(rdev, wqe_mode); 1562 + if (rc) 1563 + goto re_dev_dealloc; 1475 1564 1476 - switch (re_work->event) { 1477 - case NETDEV_UP: 1478 - bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, 1479 - IB_EVENT_PORT_ACTIVE); 1480 - break; 1481 - case NETDEV_DOWN: 1482 - bnxt_re_dev_stop(rdev); 1483 - break; 1484 - case NETDEV_CHANGE: 1485 - if (!netif_carrier_ok(rdev->netdev)) 1486 - bnxt_re_dev_stop(rdev); 1487 - else if (netif_carrier_ok(rdev->netdev)) 1488 - bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, 1489 - IB_EVENT_PORT_ACTIVE); 1490 - ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed, 1491 - &rdev->active_width); 1492 - break; 1493 - default: 1494 - break; 1565 + rc = bnxt_re_ib_init(rdev); 1566 + if (rc) { 1567 + pr_err("Failed to register with IB: %s", 1568 + aux_priv->aux_dev.name); 1569 + goto re_dev_uninit; 1495 1570 } 1496 - ib_device_put(&rdev->ibdev); 1571 + auxiliary_set_drvdata(adev, rdev); 1572 + 1573 + return 0; 1574 + 1575 + re_dev_uninit: 1576 + bnxt_re_dev_uninit(rdev); 1577 + re_dev_dealloc: 1578 + ib_dealloc_device(&rdev->ibdev); 1497 1579 exit: 1498 - put_device(&rdev->ibdev.dev); 1499 - kfree(re_work); 1580 + return rc; 1500 1581 } 1501 1582 1502 1583 /* ··· 1425 1690 unsigned long event, void *ptr) 1426 1691 { 1427 1692 struct net_device *real_dev, *netdev = netdev_notifier_info_to_dev(ptr); 1428 - struct bnxt_re_work *re_work; 1429 1693 struct bnxt_re_dev *rdev; 1430 - int rc = 0; 1431 - bool sch_work = false; 1432 - bool release = true; 1433 1694 1434 1695 real_dev = rdma_vlan_dev_real_dev(netdev); 1435 1696 if (!real_dev) 1436 1697 real_dev = netdev; 1437 1698 1438 - rdev = bnxt_re_from_netdev(real_dev); 1439 - if (!rdev && event != NETDEV_REGISTER) 1440 - return NOTIFY_OK; 1441 - 1442 1699 if (real_dev != netdev) 1443 1700 goto exit; 1444 1701 1702 + rdev = bnxt_re_from_netdev(real_dev); 1703 + if (!rdev) 1704 + return NOTIFY_DONE; 1705 + 1706 + 1445 1707 switch (event) { 1446 - case NETDEV_REGISTER: 1447 - if (rdev) 1448 - break; 1449 - rc = bnxt_re_add_device(&rdev, real_dev, 1450 - BNXT_QPLIB_WQE_MODE_STATIC); 1451 - if (!rc) 1452 - sch_work = true; 1453 - release = false; 1708 + case NETDEV_UP: 1709 + case NETDEV_DOWN: 1710 + case NETDEV_CHANGE: 1711 + bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, 1712 + netif_carrier_ok(real_dev) ? 1713 + IB_EVENT_PORT_ACTIVE : 1714 + IB_EVENT_PORT_ERR); 1454 1715 break; 1455 - 1456 - case NETDEV_UNREGISTER: 1457 - ib_unregister_device_queued(&rdev->ibdev); 1458 - break; 1459 - 1460 1716 default: 1461 - sch_work = true; 1462 1717 break; 1463 1718 } 1464 - if (sch_work) { 1465 - /* Allocate for the deferred task */ 1466 - re_work = kzalloc(sizeof(*re_work), GFP_KERNEL); 1467 - if (re_work) { 1468 - get_device(&rdev->ibdev.dev); 1469 - re_work->rdev = rdev; 1470 - re_work->event = event; 1471 - re_work->vlan_dev = (real_dev == netdev ? 1472 - NULL : netdev); 1473 - INIT_WORK(&re_work->work, bnxt_re_task); 1474 - queue_work(bnxt_re_wq, &re_work->work); 1475 - } 1476 - } 1477 - 1719 + ib_device_put(&rdev->ibdev); 1478 1720 exit: 1479 - if (rdev && release) 1480 - ib_device_put(&rdev->ibdev); 1481 1721 return NOTIFY_DONE; 1482 1722 } 1483 1723 1484 - static struct notifier_block bnxt_re_netdev_notifier = { 1485 - .notifier_call = bnxt_re_netdev_event 1724 + #define BNXT_ADEV_NAME "bnxt_en" 1725 + 1726 + static void bnxt_re_remove(struct auxiliary_device *adev) 1727 + { 1728 + struct bnxt_re_dev *rdev = auxiliary_get_drvdata(adev); 1729 + 1730 + if (!rdev) 1731 + return; 1732 + 1733 + mutex_lock(&bnxt_re_mutex); 1734 + if (rdev->nb.notifier_call) { 1735 + unregister_netdevice_notifier(&rdev->nb); 1736 + rdev->nb.notifier_call = NULL; 1737 + } else { 1738 + /* If notifier is null, we should have already done a 1739 + * clean up before coming here. 1740 + */ 1741 + goto skip_remove; 1742 + } 1743 + 1744 + ib_unregister_device(&rdev->ibdev); 1745 + ib_dealloc_device(&rdev->ibdev); 1746 + bnxt_re_dev_uninit(rdev); 1747 + skip_remove: 1748 + mutex_unlock(&bnxt_re_mutex); 1749 + } 1750 + 1751 + static int bnxt_re_probe(struct auxiliary_device *adev, 1752 + const struct auxiliary_device_id *id) 1753 + { 1754 + struct bnxt_re_dev *rdev; 1755 + int rc; 1756 + 1757 + mutex_lock(&bnxt_re_mutex); 1758 + rc = bnxt_re_add_device(adev, BNXT_QPLIB_WQE_MODE_STATIC); 1759 + if (rc) { 1760 + mutex_unlock(&bnxt_re_mutex); 1761 + return rc; 1762 + } 1763 + 1764 + rdev = auxiliary_get_drvdata(adev); 1765 + 1766 + rdev->nb.notifier_call = bnxt_re_netdev_event; 1767 + rc = register_netdevice_notifier(&rdev->nb); 1768 + if (rc) { 1769 + rdev->nb.notifier_call = NULL; 1770 + pr_err("%s: Cannot register to netdevice_notifier", 1771 + ROCE_DRV_MODULE_NAME); 1772 + goto err; 1773 + } 1774 + 1775 + mutex_unlock(&bnxt_re_mutex); 1776 + return 0; 1777 + 1778 + err: 1779 + mutex_unlock(&bnxt_re_mutex); 1780 + bnxt_re_remove(adev); 1781 + 1782 + return rc; 1783 + } 1784 + 1785 + static int bnxt_re_suspend(struct auxiliary_device *adev, pm_message_t state) 1786 + { 1787 + struct bnxt_re_dev *rdev = auxiliary_get_drvdata(adev); 1788 + 1789 + if (!rdev) 1790 + return 0; 1791 + 1792 + mutex_lock(&bnxt_re_mutex); 1793 + /* L2 driver may invoke this callback during device error/crash or device 1794 + * reset. Current RoCE driver doesn't recover the device in case of 1795 + * error. Handle the error by dispatching fatal events to all qps 1796 + * ie. by calling bnxt_re_dev_stop and release the MSIx vectors as 1797 + * L2 driver want to modify the MSIx table. 1798 + */ 1799 + 1800 + ibdev_info(&rdev->ibdev, "Handle device suspend call"); 1801 + /* Check the current device state from bnxt_en_dev and move the 1802 + * device to detached state if FW_FATAL_COND is set. 1803 + * This prevents more commands to HW during clean-up, 1804 + * in case the device is already in error. 1805 + */ 1806 + if (test_bit(BNXT_STATE_FW_FATAL_COND, &rdev->en_dev->en_state)) 1807 + set_bit(ERR_DEVICE_DETACHED, &rdev->rcfw.cmdq.flags); 1808 + 1809 + bnxt_re_dev_stop(rdev); 1810 + bnxt_re_stop_irq(rdev); 1811 + /* Move the device states to detached and avoid sending any more 1812 + * commands to HW 1813 + */ 1814 + set_bit(BNXT_RE_FLAG_ERR_DEVICE_DETACHED, &rdev->flags); 1815 + set_bit(ERR_DEVICE_DETACHED, &rdev->rcfw.cmdq.flags); 1816 + mutex_unlock(&bnxt_re_mutex); 1817 + 1818 + return 0; 1819 + } 1820 + 1821 + static int bnxt_re_resume(struct auxiliary_device *adev) 1822 + { 1823 + struct bnxt_re_dev *rdev = auxiliary_get_drvdata(adev); 1824 + 1825 + if (!rdev) 1826 + return 0; 1827 + 1828 + mutex_lock(&bnxt_re_mutex); 1829 + /* L2 driver may invoke this callback during device recovery, resume. 1830 + * reset. Current RoCE driver doesn't recover the device in case of 1831 + * error. Handle the error by dispatching fatal events to all qps 1832 + * ie. by calling bnxt_re_dev_stop and release the MSIx vectors as 1833 + * L2 driver want to modify the MSIx table. 1834 + */ 1835 + 1836 + ibdev_info(&rdev->ibdev, "Handle device resume call"); 1837 + mutex_unlock(&bnxt_re_mutex); 1838 + 1839 + return 0; 1840 + } 1841 + 1842 + static const struct auxiliary_device_id bnxt_re_id_table[] = { 1843 + { .name = BNXT_ADEV_NAME ".rdma", }, 1844 + {}, 1845 + }; 1846 + 1847 + MODULE_DEVICE_TABLE(auxiliary, bnxt_re_id_table); 1848 + 1849 + static struct auxiliary_driver bnxt_re_driver = { 1850 + .name = "rdma", 1851 + .probe = bnxt_re_probe, 1852 + .remove = bnxt_re_remove, 1853 + .shutdown = bnxt_re_shutdown, 1854 + .suspend = bnxt_re_suspend, 1855 + .resume = bnxt_re_resume, 1856 + .id_table = bnxt_re_id_table, 1486 1857 }; 1487 1858 1488 1859 static int __init bnxt_re_mod_init(void) ··· 1596 1755 int rc = 0; 1597 1756 1598 1757 pr_info("%s: %s", ROCE_DRV_MODULE_NAME, version); 1599 - 1600 - bnxt_re_wq = create_singlethread_workqueue("bnxt_re"); 1601 - if (!bnxt_re_wq) 1602 - return -ENOMEM; 1603 - 1604 - INIT_LIST_HEAD(&bnxt_re_dev_list); 1605 - 1606 - rc = register_netdevice_notifier(&bnxt_re_netdev_notifier); 1758 + rc = auxiliary_driver_register(&bnxt_re_driver); 1607 1759 if (rc) { 1608 - pr_err("%s: Cannot register to netdevice_notifier", 1609 - ROCE_DRV_MODULE_NAME); 1610 - goto err_netdev; 1760 + pr_err("%s: Failed to register auxiliary driver\n", 1761 + ROCE_DRV_MODULE_NAME); 1762 + return rc; 1611 1763 } 1612 1764 return 0; 1613 - 1614 - err_netdev: 1615 - destroy_workqueue(bnxt_re_wq); 1616 - 1617 - return rc; 1618 1765 } 1619 1766 1620 1767 static void __exit bnxt_re_mod_exit(void) 1621 1768 { 1622 - struct bnxt_re_dev *rdev; 1623 - 1624 - unregister_netdevice_notifier(&bnxt_re_netdev_notifier); 1625 - if (bnxt_re_wq) 1626 - destroy_workqueue(bnxt_re_wq); 1627 - list_for_each_entry(rdev, &bnxt_re_dev_list, list) { 1628 - /* VF device removal should be called before the removal 1629 - * of PF device. Queue VFs unregister first, so that VFs 1630 - * shall be removed before the PF during the call of 1631 - * ib_unregister_driver. 1632 - */ 1633 - if (rdev->is_virtfn) 1634 - ib_unregister_device(&rdev->ibdev); 1635 - } 1636 - ib_unregister_driver(RDMA_DRIVER_BNXT_RE); 1769 + auxiliary_driver_unregister(&bnxt_re_driver); 1637 1770 } 1638 1771 1639 1772 module_init(bnxt_re_mod_init);
+1
drivers/net/ethernet/broadcom/Kconfig
··· 213 213 select NET_DEVLINK 214 214 select PAGE_POOL 215 215 select DIMLIB 216 + select AUXILIARY_BUS 216 217 help 217 218 This driver supports Broadcom NetXtreme-C/E 10/25/40/50 gigabit 218 219 Ethernet cards. To compile this driver as a module, choose M here:
+6 -4
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 2414 2414 } 2415 2415 bnxt_queue_sp_work(bp); 2416 2416 async_event_process_exit: 2417 - bnxt_ulp_async_events(bp, cmpl); 2418 2417 return 0; 2419 2418 } 2420 2419 ··· 5537 5538 #endif 5538 5539 if ((bp->flags & BNXT_FLAG_STRIP_VLAN) || def_vlan) 5539 5540 req->flags |= cpu_to_le32(VNIC_CFG_REQ_FLAGS_VLAN_STRIP_MODE); 5540 - if (!vnic_id && bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) 5541 + if (!vnic_id && bnxt_ulp_registered(bp->edev)) 5541 5542 req->flags |= cpu_to_le32(bnxt_get_roce_vnic_mode(bp)); 5542 5543 5543 5544 return hwrm_req_send(bp, req); ··· 13180 13181 if (BNXT_PF(bp)) 13181 13182 bnxt_sriov_disable(bp); 13182 13183 13184 + bnxt_rdma_aux_device_uninit(bp); 13185 + 13183 13186 bnxt_ptp_clear(bp); 13184 13187 pci_disable_pcie_error_reporting(pdev); 13185 13188 unregister_netdev(dev); ··· 13777 13776 13778 13777 bnxt_dl_fw_reporters_create(bp); 13779 13778 13779 + bnxt_rdma_aux_device_init(bp); 13780 + 13780 13781 bnxt_print_device_info(bp); 13781 13782 13782 13783 pci_save_state(pdev); 13783 - return 0; 13784 13784 13785 + return 0; 13785 13786 init_err_cleanup: 13786 13787 bnxt_dl_unregister(bp); 13787 13788 init_err_dl: ··· 13827 13824 if (netif_running(dev)) 13828 13825 dev_close(dev); 13829 13826 13830 - bnxt_ulp_shutdown(bp); 13831 13827 bnxt_clear_int_mode(bp); 13832 13828 pci_disable_device(pdev); 13833 13829
+8
drivers/net/ethernet/broadcom/bnxt/bnxt.h
··· 24 24 #include <linux/interrupt.h> 25 25 #include <linux/rhashtable.h> 26 26 #include <linux/crash_dump.h> 27 + #include <linux/auxiliary_bus.h> 27 28 #include <net/devlink.h> 28 29 #include <net/dst_metadata.h> 29 30 #include <net/xdp.h> ··· 1632 1631 #define BNXT_FW_IF_RETRY 10 1633 1632 #define BNXT_FW_SLOT_RESET_RETRY 4 1634 1633 1634 + struct bnxt_aux_priv { 1635 + struct auxiliary_device aux_dev; 1636 + struct bnxt_en_dev *edev; 1637 + int id; 1638 + }; 1639 + 1635 1640 enum board_idx { 1636 1641 BCM57301, 1637 1642 BCM57302, ··· 1859 1852 #define BNXT_CHIP_P4_PLUS(bp) \ 1860 1853 (BNXT_CHIP_P4(bp) || BNXT_CHIP_P5(bp)) 1861 1854 1855 + struct bnxt_aux_priv *aux_priv; 1862 1856 struct bnxt_en_dev *edev; 1863 1857 1864 1858 struct bnxt_napi **bnapi;
+1 -6
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
··· 749 749 *num_vfs = rc; 750 750 } 751 751 752 - bnxt_ulp_sriov_cfg(bp, *num_vfs); 753 752 return 0; 754 753 } 755 754 ··· 822 823 goto err_out2; 823 824 824 825 rc = pci_enable_sriov(bp->pdev, *num_vfs); 825 - if (rc) { 826 - bnxt_ulp_sriov_cfg(bp, 0); 826 + if (rc) 827 827 goto err_out2; 828 - } 829 828 830 829 return 0; 831 830 ··· 869 872 rtnl_lock(); 870 873 bnxt_restore_pf_fw_resources(bp); 871 874 rtnl_unlock(); 872 - 873 - bnxt_ulp_sriov_cfg(bp, 0); 874 875 } 875 876 876 877 int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs)
+203 -289
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
··· 19 19 #include <linux/irq.h> 20 20 #include <asm/byteorder.h> 21 21 #include <linux/bitmap.h> 22 + #include <linux/auxiliary_bus.h> 22 23 23 24 #include "bnxt_hsi.h" 24 25 #include "bnxt.h" 25 26 #include "bnxt_hwrm.h" 26 27 #include "bnxt_ulp.h" 27 28 28 - static int bnxt_register_dev(struct bnxt_en_dev *edev, unsigned int ulp_id, 29 - struct bnxt_ulp_ops *ulp_ops, void *handle) 30 - { 31 - struct net_device *dev = edev->net; 32 - struct bnxt *bp = netdev_priv(dev); 33 - struct bnxt_ulp *ulp; 34 - 35 - ASSERT_RTNL(); 36 - if (ulp_id >= BNXT_MAX_ULP) 37 - return -EINVAL; 38 - 39 - ulp = &edev->ulp_tbl[ulp_id]; 40 - if (rcu_access_pointer(ulp->ulp_ops)) { 41 - netdev_err(bp->dev, "ulp id %d already registered\n", ulp_id); 42 - return -EBUSY; 43 - } 44 - if (ulp_id == BNXT_ROCE_ULP) { 45 - unsigned int max_stat_ctxs; 46 - 47 - max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp); 48 - if (max_stat_ctxs <= BNXT_MIN_ROCE_STAT_CTXS || 49 - bp->cp_nr_rings == max_stat_ctxs) 50 - return -ENOMEM; 51 - } 52 - 53 - atomic_set(&ulp->ref_count, 0); 54 - ulp->handle = handle; 55 - rcu_assign_pointer(ulp->ulp_ops, ulp_ops); 56 - 57 - if (ulp_id == BNXT_ROCE_ULP) { 58 - if (test_bit(BNXT_STATE_OPEN, &bp->state)) 59 - bnxt_hwrm_vnic_cfg(bp, 0); 60 - } 61 - 62 - return 0; 63 - } 64 - 65 - static int bnxt_unregister_dev(struct bnxt_en_dev *edev, unsigned int ulp_id) 66 - { 67 - struct net_device *dev = edev->net; 68 - struct bnxt *bp = netdev_priv(dev); 69 - struct bnxt_ulp *ulp; 70 - int i = 0; 71 - 72 - ASSERT_RTNL(); 73 - if (ulp_id >= BNXT_MAX_ULP) 74 - return -EINVAL; 75 - 76 - ulp = &edev->ulp_tbl[ulp_id]; 77 - if (!rcu_access_pointer(ulp->ulp_ops)) { 78 - netdev_err(bp->dev, "ulp id %d not registered\n", ulp_id); 79 - return -EINVAL; 80 - } 81 - if (ulp_id == BNXT_ROCE_ULP && ulp->msix_requested) 82 - edev->en_ops->bnxt_free_msix(edev, ulp_id); 83 - 84 - if (ulp->max_async_event_id) 85 - bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, true); 86 - 87 - RCU_INIT_POINTER(ulp->ulp_ops, NULL); 88 - synchronize_rcu(); 89 - ulp->max_async_event_id = 0; 90 - ulp->async_events_bmap = NULL; 91 - while (atomic_read(&ulp->ref_count) != 0 && i < 10) { 92 - msleep(100); 93 - i++; 94 - } 95 - return 0; 96 - } 29 + static DEFINE_IDA(bnxt_aux_dev_ids); 97 30 98 31 static void bnxt_fill_msix_vecs(struct bnxt *bp, struct bnxt_msix_entry *ent) 99 32 { 100 33 struct bnxt_en_dev *edev = bp->edev; 101 34 int num_msix, idx, i; 102 35 103 - num_msix = edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested; 104 - idx = edev->ulp_tbl[BNXT_ROCE_ULP].msix_base; 36 + if (!edev->ulp_tbl->msix_requested) { 37 + netdev_warn(bp->dev, "Requested MSI-X vectors insufficient\n"); 38 + return; 39 + } 40 + num_msix = edev->ulp_tbl->msix_requested; 41 + idx = edev->ulp_tbl->msix_base; 105 42 for (i = 0; i < num_msix; i++) { 106 43 ent[i].vector = bp->irq_tbl[idx + i].vector; 107 44 ent[i].ring_idx = idx + i; ··· 52 115 } 53 116 } 54 117 55 - static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, unsigned int ulp_id, 56 - struct bnxt_msix_entry *ent, int num_msix) 118 + int bnxt_register_dev(struct bnxt_en_dev *edev, 119 + struct bnxt_ulp_ops *ulp_ops, 120 + void *handle) 57 121 { 58 122 struct net_device *dev = edev->net; 59 123 struct bnxt *bp = netdev_priv(dev); 60 - struct bnxt_hw_resc *hw_resc; 61 - int max_idx, max_cp_rings; 62 - int avail_msix, idx; 63 - int total_vecs; 64 - int rc = 0; 124 + unsigned int max_stat_ctxs; 125 + struct bnxt_ulp *ulp; 65 126 66 - ASSERT_RTNL(); 67 - if (ulp_id != BNXT_ROCE_ULP) 68 - return -EINVAL; 69 - 70 - if (!(bp->flags & BNXT_FLAG_USING_MSIX)) 71 - return -ENODEV; 72 - 73 - if (edev->ulp_tbl[ulp_id].msix_requested) 74 - return -EAGAIN; 75 - 76 - max_cp_rings = bnxt_get_max_func_cp_rings(bp); 77 - avail_msix = bnxt_get_avail_msix(bp, num_msix); 78 - if (!avail_msix) 127 + max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp); 128 + if (max_stat_ctxs <= BNXT_MIN_ROCE_STAT_CTXS || 129 + bp->cp_nr_rings == max_stat_ctxs) 79 130 return -ENOMEM; 80 - if (avail_msix > num_msix) 81 - avail_msix = num_msix; 82 131 83 - if (BNXT_NEW_RM(bp)) { 84 - idx = bp->cp_nr_rings; 85 - } else { 86 - max_idx = min_t(int, bp->total_irqs, max_cp_rings); 87 - idx = max_idx - avail_msix; 88 - } 89 - edev->ulp_tbl[ulp_id].msix_base = idx; 90 - edev->ulp_tbl[ulp_id].msix_requested = avail_msix; 91 - hw_resc = &bp->hw_resc; 92 - total_vecs = idx + avail_msix; 93 - if (bp->total_irqs < total_vecs || 94 - (BNXT_NEW_RM(bp) && hw_resc->resv_irqs < total_vecs)) { 95 - if (netif_running(dev)) { 96 - bnxt_close_nic(bp, true, false); 97 - rc = bnxt_open_nic(bp, true, false); 98 - } else { 99 - rc = bnxt_reserve_rings(bp, true); 100 - } 101 - } 102 - if (rc) { 103 - edev->ulp_tbl[ulp_id].msix_requested = 0; 104 - return -EAGAIN; 105 - } 132 + ulp = edev->ulp_tbl; 133 + if (!ulp) 134 + return -ENOMEM; 106 135 107 - if (BNXT_NEW_RM(bp)) { 108 - int resv_msix; 136 + ulp->handle = handle; 137 + rcu_assign_pointer(ulp->ulp_ops, ulp_ops); 109 138 110 - resv_msix = hw_resc->resv_irqs - bp->cp_nr_rings; 111 - avail_msix = min_t(int, resv_msix, avail_msix); 112 - edev->ulp_tbl[ulp_id].msix_requested = avail_msix; 113 - } 114 - bnxt_fill_msix_vecs(bp, ent); 139 + if (test_bit(BNXT_STATE_OPEN, &bp->state)) 140 + bnxt_hwrm_vnic_cfg(bp, 0); 141 + 142 + bnxt_fill_msix_vecs(bp, bp->edev->msix_entries); 115 143 edev->flags |= BNXT_EN_FLAG_MSIX_REQUESTED; 116 - return avail_msix; 117 - } 118 - 119 - static int bnxt_free_msix_vecs(struct bnxt_en_dev *edev, unsigned int ulp_id) 120 - { 121 - struct net_device *dev = edev->net; 122 - struct bnxt *bp = netdev_priv(dev); 123 - 124 - ASSERT_RTNL(); 125 - if (ulp_id != BNXT_ROCE_ULP) 126 - return -EINVAL; 127 - 128 - if (!(edev->flags & BNXT_EN_FLAG_MSIX_REQUESTED)) 129 - return 0; 130 - 131 - edev->ulp_tbl[ulp_id].msix_requested = 0; 132 - edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED; 133 - if (netif_running(dev) && !(edev->flags & BNXT_EN_FLAG_ULP_STOPPED)) { 134 - bnxt_close_nic(bp, true, false); 135 - bnxt_open_nic(bp, true, false); 136 - } 137 144 return 0; 138 145 } 146 + EXPORT_SYMBOL(bnxt_register_dev); 147 + 148 + void bnxt_unregister_dev(struct bnxt_en_dev *edev) 149 + { 150 + struct net_device *dev = edev->net; 151 + struct bnxt *bp = netdev_priv(dev); 152 + struct bnxt_ulp *ulp; 153 + int i = 0; 154 + 155 + ulp = edev->ulp_tbl; 156 + if (ulp->msix_requested) 157 + edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED; 158 + 159 + if (ulp->max_async_event_id) 160 + bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, true); 161 + 162 + RCU_INIT_POINTER(ulp->ulp_ops, NULL); 163 + synchronize_rcu(); 164 + ulp->max_async_event_id = 0; 165 + ulp->async_events_bmap = NULL; 166 + while (atomic_read(&ulp->ref_count) != 0 && i < 10) { 167 + msleep(100); 168 + i++; 169 + } 170 + return; 171 + } 172 + EXPORT_SYMBOL(bnxt_unregister_dev); 139 173 140 174 int bnxt_get_ulp_msix_num(struct bnxt *bp) 141 175 { 142 - if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { 143 - struct bnxt_en_dev *edev = bp->edev; 176 + u32 roce_msix = BNXT_VF(bp) ? 177 + BNXT_MAX_VF_ROCE_MSIX : BNXT_MAX_ROCE_MSIX; 144 178 145 - return edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested; 146 - } 147 - return 0; 179 + return ((bp->flags & BNXT_FLAG_ROCE_CAP) ? 180 + min_t(u32, roce_msix, num_online_cpus()) : 0); 148 181 } 149 182 150 183 int bnxt_get_ulp_msix_base(struct bnxt *bp) 151 184 { 152 - if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { 185 + if (bnxt_ulp_registered(bp->edev)) { 153 186 struct bnxt_en_dev *edev = bp->edev; 154 187 155 - if (edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested) 156 - return edev->ulp_tbl[BNXT_ROCE_ULP].msix_base; 188 + if (edev->ulp_tbl->msix_requested) 189 + return edev->ulp_tbl->msix_base; 157 190 } 158 191 return 0; 159 192 } 160 193 161 194 int bnxt_get_ulp_stat_ctxs(struct bnxt *bp) 162 195 { 163 - if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { 196 + if (bnxt_ulp_registered(bp->edev)) { 164 197 struct bnxt_en_dev *edev = bp->edev; 165 198 166 - if (edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested) 199 + if (edev->ulp_tbl->msix_requested) 167 200 return BNXT_MIN_ROCE_STAT_CTXS; 168 201 } 169 202 170 203 return 0; 171 204 } 172 205 173 - static int bnxt_send_msg(struct bnxt_en_dev *edev, unsigned int ulp_id, 206 + int bnxt_send_msg(struct bnxt_en_dev *edev, 174 207 struct bnxt_fw_msg *fw_msg) 175 208 { 176 209 struct net_device *dev = edev->net; ··· 150 243 u32 resp_len; 151 244 int rc; 152 245 153 - if (ulp_id != BNXT_ROCE_ULP && bp->fw_reset_state) 246 + if (bp->fw_reset_state) 154 247 return -EBUSY; 155 248 156 249 rc = hwrm_req_init(bp, req, 0 /* don't care */); ··· 174 267 hwrm_req_drop(bp, req); 175 268 return rc; 176 269 } 177 - 178 - static void bnxt_ulp_get(struct bnxt_ulp *ulp) 179 - { 180 - atomic_inc(&ulp->ref_count); 181 - } 182 - 183 - static void bnxt_ulp_put(struct bnxt_ulp *ulp) 184 - { 185 - atomic_dec(&ulp->ref_count); 186 - } 270 + EXPORT_SYMBOL(bnxt_send_msg); 187 271 188 272 void bnxt_ulp_stop(struct bnxt *bp) 189 273 { 274 + struct bnxt_aux_priv *aux_priv = bp->aux_priv; 190 275 struct bnxt_en_dev *edev = bp->edev; 191 - struct bnxt_ulp_ops *ops; 192 - int i; 193 276 194 277 if (!edev) 195 278 return; 196 279 197 280 edev->flags |= BNXT_EN_FLAG_ULP_STOPPED; 198 - for (i = 0; i < BNXT_MAX_ULP; i++) { 199 - struct bnxt_ulp *ulp = &edev->ulp_tbl[i]; 281 + if (aux_priv) { 282 + struct auxiliary_device *adev; 200 283 201 - ops = rtnl_dereference(ulp->ulp_ops); 202 - if (!ops || !ops->ulp_stop) 203 - continue; 204 - ops->ulp_stop(ulp->handle); 284 + adev = &aux_priv->aux_dev; 285 + if (adev->dev.driver) { 286 + struct auxiliary_driver *adrv; 287 + pm_message_t pm = {}; 288 + 289 + adrv = to_auxiliary_drv(adev->dev.driver); 290 + edev->en_state = bp->state; 291 + adrv->suspend(adev, pm); 292 + } 205 293 } 206 294 } 207 295 208 296 void bnxt_ulp_start(struct bnxt *bp, int err) 209 297 { 298 + struct bnxt_aux_priv *aux_priv = bp->aux_priv; 210 299 struct bnxt_en_dev *edev = bp->edev; 211 - struct bnxt_ulp_ops *ops; 212 - int i; 213 300 214 301 if (!edev) 215 302 return; ··· 213 312 if (err) 214 313 return; 215 314 216 - for (i = 0; i < BNXT_MAX_ULP; i++) { 217 - struct bnxt_ulp *ulp = &edev->ulp_tbl[i]; 315 + if (aux_priv) { 316 + struct auxiliary_device *adev; 218 317 219 - ops = rtnl_dereference(ulp->ulp_ops); 220 - if (!ops || !ops->ulp_start) 221 - continue; 222 - ops->ulp_start(ulp->handle); 223 - } 224 - } 318 + adev = &aux_priv->aux_dev; 319 + if (adev->dev.driver) { 320 + struct auxiliary_driver *adrv; 225 321 226 - void bnxt_ulp_sriov_cfg(struct bnxt *bp, int num_vfs) 227 - { 228 - struct bnxt_en_dev *edev = bp->edev; 229 - struct bnxt_ulp_ops *ops; 230 - int i; 231 - 232 - if (!edev) 233 - return; 234 - 235 - for (i = 0; i < BNXT_MAX_ULP; i++) { 236 - struct bnxt_ulp *ulp = &edev->ulp_tbl[i]; 237 - 238 - rcu_read_lock(); 239 - ops = rcu_dereference(ulp->ulp_ops); 240 - if (!ops || !ops->ulp_sriov_config) { 241 - rcu_read_unlock(); 242 - continue; 322 + adrv = to_auxiliary_drv(adev->dev.driver); 323 + edev->en_state = bp->state; 324 + adrv->resume(adev); 243 325 } 244 - bnxt_ulp_get(ulp); 245 - rcu_read_unlock(); 246 - ops->ulp_sriov_config(ulp->handle, num_vfs); 247 - bnxt_ulp_put(ulp); 248 326 } 249 - } 250 327 251 - void bnxt_ulp_shutdown(struct bnxt *bp) 252 - { 253 - struct bnxt_en_dev *edev = bp->edev; 254 - struct bnxt_ulp_ops *ops; 255 - int i; 256 - 257 - if (!edev) 258 - return; 259 - 260 - for (i = 0; i < BNXT_MAX_ULP; i++) { 261 - struct bnxt_ulp *ulp = &edev->ulp_tbl[i]; 262 - 263 - ops = rtnl_dereference(ulp->ulp_ops); 264 - if (!ops || !ops->ulp_shutdown) 265 - continue; 266 - ops->ulp_shutdown(ulp->handle); 267 - } 268 328 } 269 329 270 330 void bnxt_ulp_irq_stop(struct bnxt *bp) ··· 236 374 if (!edev || !(edev->flags & BNXT_EN_FLAG_MSIX_REQUESTED)) 237 375 return; 238 376 239 - if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { 240 - struct bnxt_ulp *ulp = &edev->ulp_tbl[BNXT_ROCE_ULP]; 377 + if (bnxt_ulp_registered(bp->edev)) { 378 + struct bnxt_ulp *ulp = edev->ulp_tbl; 241 379 242 380 if (!ulp->msix_requested) 243 381 return; ··· 257 395 if (!edev || !(edev->flags & BNXT_EN_FLAG_MSIX_REQUESTED)) 258 396 return; 259 397 260 - if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { 261 - struct bnxt_ulp *ulp = &edev->ulp_tbl[BNXT_ROCE_ULP]; 398 + if (bnxt_ulp_registered(bp->edev)) { 399 + struct bnxt_ulp *ulp = edev->ulp_tbl; 262 400 struct bnxt_msix_entry *ent = NULL; 263 401 264 402 if (!ulp->msix_requested) ··· 280 418 } 281 419 } 282 420 283 - void bnxt_ulp_async_events(struct bnxt *bp, struct hwrm_async_event_cmpl *cmpl) 284 - { 285 - u16 event_id = le16_to_cpu(cmpl->event_id); 286 - struct bnxt_en_dev *edev = bp->edev; 287 - struct bnxt_ulp_ops *ops; 288 - int i; 289 - 290 - if (!edev) 291 - return; 292 - 293 - rcu_read_lock(); 294 - for (i = 0; i < BNXT_MAX_ULP; i++) { 295 - struct bnxt_ulp *ulp = &edev->ulp_tbl[i]; 296 - 297 - ops = rcu_dereference(ulp->ulp_ops); 298 - if (!ops || !ops->ulp_async_notifier) 299 - continue; 300 - if (!ulp->async_events_bmap || 301 - event_id > ulp->max_async_event_id) 302 - continue; 303 - 304 - /* Read max_async_event_id first before testing the bitmap. */ 305 - smp_rmb(); 306 - if (test_bit(event_id, ulp->async_events_bmap)) 307 - ops->ulp_async_notifier(ulp->handle, cmpl); 308 - } 309 - rcu_read_unlock(); 310 - } 311 - 312 - static int bnxt_register_async_events(struct bnxt_en_dev *edev, unsigned int ulp_id, 313 - unsigned long *events_bmap, u16 max_id) 421 + int bnxt_register_async_events(struct bnxt_en_dev *edev, 422 + unsigned long *events_bmap, 423 + u16 max_id) 314 424 { 315 425 struct net_device *dev = edev->net; 316 426 struct bnxt *bp = netdev_priv(dev); 317 427 struct bnxt_ulp *ulp; 318 428 319 - if (ulp_id >= BNXT_MAX_ULP) 320 - return -EINVAL; 321 - 322 - ulp = &edev->ulp_tbl[ulp_id]; 429 + ulp = edev->ulp_tbl; 323 430 ulp->async_events_bmap = events_bmap; 324 431 /* Make sure bnxt_ulp_async_events() sees this order */ 325 432 smp_wmb(); ··· 296 465 bnxt_hwrm_func_drv_rgtr(bp, events_bmap, max_id + 1, true); 297 466 return 0; 298 467 } 468 + EXPORT_SYMBOL(bnxt_register_async_events); 299 469 300 - static const struct bnxt_en_ops bnxt_en_ops_tbl = { 301 - .bnxt_register_device = bnxt_register_dev, 302 - .bnxt_unregister_device = bnxt_unregister_dev, 303 - .bnxt_request_msix = bnxt_req_msix_vecs, 304 - .bnxt_free_msix = bnxt_free_msix_vecs, 305 - .bnxt_send_fw_msg = bnxt_send_msg, 306 - .bnxt_register_fw_async_events = bnxt_register_async_events, 307 - }; 308 - 309 - struct bnxt_en_dev *bnxt_ulp_probe(struct net_device *dev) 470 + void bnxt_rdma_aux_device_uninit(struct bnxt *bp) 310 471 { 311 - struct bnxt *bp = netdev_priv(dev); 312 - struct bnxt_en_dev *edev; 472 + struct bnxt_aux_priv *aux_priv; 473 + struct auxiliary_device *adev; 313 474 314 - edev = bp->edev; 315 - if (!edev) { 316 - edev = kzalloc(sizeof(*edev), GFP_KERNEL); 317 - if (!edev) 318 - return ERR_PTR(-ENOMEM); 319 - edev->en_ops = &bnxt_en_ops_tbl; 320 - edev->net = dev; 321 - edev->pdev = bp->pdev; 322 - edev->l2_db_size = bp->db_size; 323 - edev->l2_db_size_nc = bp->db_size; 324 - bp->edev = edev; 325 - } 326 - edev->flags &= ~BNXT_EN_FLAG_ROCE_CAP; 475 + /* Skip if no auxiliary device init was done. */ 476 + if (!(bp->flags & BNXT_FLAG_ROCE_CAP)) 477 + return; 478 + 479 + aux_priv = bp->aux_priv; 480 + adev = &aux_priv->aux_dev; 481 + auxiliary_device_delete(adev); 482 + auxiliary_device_uninit(adev); 483 + } 484 + 485 + static void bnxt_aux_dev_release(struct device *dev) 486 + { 487 + struct bnxt_aux_priv *aux_priv = 488 + container_of(dev, struct bnxt_aux_priv, aux_dev.dev); 489 + 490 + ida_free(&bnxt_aux_dev_ids, aux_priv->id); 491 + kfree(aux_priv->edev->ulp_tbl); 492 + kfree(aux_priv->edev); 493 + kfree(aux_priv); 494 + } 495 + 496 + static void bnxt_set_edev_info(struct bnxt_en_dev *edev, struct bnxt *bp) 497 + { 498 + edev->net = bp->dev; 499 + edev->pdev = bp->pdev; 500 + edev->l2_db_size = bp->db_size; 501 + edev->l2_db_size_nc = bp->db_size; 502 + 327 503 if (bp->flags & BNXT_FLAG_ROCEV1_CAP) 328 504 edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; 329 505 if (bp->flags & BNXT_FLAG_ROCEV2_CAP) 330 506 edev->flags |= BNXT_EN_FLAG_ROCEV2_CAP; 331 - return bp->edev; 507 + if (bp->flags & BNXT_FLAG_VF) 508 + edev->flags |= BNXT_EN_FLAG_VF; 509 + 510 + edev->chip_num = bp->chip_num; 511 + edev->hw_ring_stats_size = bp->hw_ring_stats_size; 512 + edev->pf_port_id = bp->pf.port_id; 513 + edev->en_state = bp->state; 514 + 515 + edev->ulp_tbl->msix_requested = bnxt_get_ulp_msix_num(bp); 332 516 } 333 - EXPORT_SYMBOL(bnxt_ulp_probe); 517 + 518 + void bnxt_rdma_aux_device_init(struct bnxt *bp) 519 + { 520 + struct auxiliary_device *aux_dev; 521 + struct bnxt_aux_priv *aux_priv; 522 + struct bnxt_en_dev *edev; 523 + struct bnxt_ulp *ulp; 524 + int rc; 525 + 526 + if (!(bp->flags & BNXT_FLAG_ROCE_CAP)) 527 + return; 528 + 529 + bp->aux_priv = kzalloc(sizeof(*bp->aux_priv), GFP_KERNEL); 530 + if (!bp->aux_priv) 531 + goto exit; 532 + 533 + bp->aux_priv->id = ida_alloc(&bnxt_aux_dev_ids, GFP_KERNEL); 534 + if (bp->aux_priv->id < 0) { 535 + netdev_warn(bp->dev, 536 + "ida alloc failed for ROCE auxiliary device\n"); 537 + kfree(bp->aux_priv); 538 + goto exit; 539 + } 540 + 541 + aux_priv = bp->aux_priv; 542 + aux_dev = &aux_priv->aux_dev; 543 + aux_dev->id = aux_priv->id; 544 + aux_dev->name = "rdma"; 545 + aux_dev->dev.parent = &bp->pdev->dev; 546 + aux_dev->dev.release = bnxt_aux_dev_release; 547 + 548 + rc = auxiliary_device_init(aux_dev); 549 + if (rc) { 550 + ida_free(&bnxt_aux_dev_ids, bp->aux_priv->id); 551 + kfree(bp->aux_priv); 552 + goto exit; 553 + } 554 + 555 + /* From this point, all cleanup will happen via the .release callback & 556 + * any error unwinding will need to include a call to 557 + * auxiliary_device_uninit. 558 + */ 559 + edev = kzalloc(sizeof(*edev), GFP_KERNEL); 560 + if (!edev) 561 + goto aux_dev_uninit; 562 + 563 + ulp = kzalloc(sizeof(*ulp), GFP_KERNEL); 564 + if (!ulp) 565 + goto aux_dev_uninit; 566 + 567 + edev->ulp_tbl = ulp; 568 + aux_priv->edev = edev; 569 + bp->edev = edev; 570 + bnxt_set_edev_info(edev, bp); 571 + 572 + rc = auxiliary_device_add(aux_dev); 573 + if (rc) { 574 + netdev_warn(bp->dev, 575 + "Failed to add auxiliary device for ROCE\n"); 576 + goto aux_dev_uninit; 577 + } 578 + 579 + return; 580 + 581 + aux_dev_uninit: 582 + auxiliary_device_uninit(aux_dev); 583 + exit: 584 + bp->flags &= ~BNXT_FLAG_ROCE_CAP; 585 + }
+25 -26
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h
··· 15 15 16 16 #define BNXT_MIN_ROCE_CP_RINGS 2 17 17 #define BNXT_MIN_ROCE_STAT_CTXS 1 18 + #define BNXT_MAX_ROCE_MSIX 9 19 + #define BNXT_MAX_VF_ROCE_MSIX 2 18 20 19 21 struct hwrm_async_event_cmpl; 20 22 struct bnxt; ··· 28 26 }; 29 27 30 28 struct bnxt_ulp_ops { 31 - /* async_notifier() cannot sleep (in BH context) */ 32 - void (*ulp_async_notifier)(void *, struct hwrm_async_event_cmpl *); 33 - void (*ulp_stop)(void *); 34 - void (*ulp_start)(void *); 35 - void (*ulp_sriov_config)(void *, int); 36 - void (*ulp_shutdown)(void *); 37 29 void (*ulp_irq_stop)(void *); 38 30 void (*ulp_irq_restart)(void *, struct bnxt_msix_entry *); 39 31 }; ··· 53 57 struct bnxt_en_dev { 54 58 struct net_device *net; 55 59 struct pci_dev *pdev; 60 + struct bnxt_msix_entry msix_entries[BNXT_MAX_ROCE_MSIX]; 56 61 u32 flags; 57 62 #define BNXT_EN_FLAG_ROCEV1_CAP 0x1 58 63 #define BNXT_EN_FLAG_ROCEV2_CAP 0x2 ··· 61 64 BNXT_EN_FLAG_ROCEV2_CAP) 62 65 #define BNXT_EN_FLAG_MSIX_REQUESTED 0x4 63 66 #define BNXT_EN_FLAG_ULP_STOPPED 0x8 64 - const struct bnxt_en_ops *en_ops; 65 - struct bnxt_ulp ulp_tbl[BNXT_MAX_ULP]; 67 + #define BNXT_EN_FLAG_VF 0x10 68 + #define BNXT_EN_VF(edev) ((edev)->flags & BNXT_EN_FLAG_VF) 69 + 70 + struct bnxt_ulp *ulp_tbl; 66 71 int l2_db_size; /* Doorbell BAR size in 67 72 * bytes mapped by L2 68 73 * driver. ··· 73 74 * bytes mapped as non- 74 75 * cacheable. 75 76 */ 77 + u16 chip_num; 78 + u16 hw_ring_stats_size; 79 + u16 pf_port_id; 80 + unsigned long en_state; /* Could be checked in 81 + * RoCE driver suspend 82 + * mode only. Will be 83 + * updated in resume. 84 + */ 76 85 }; 77 86 78 - struct bnxt_en_ops { 79 - int (*bnxt_register_device)(struct bnxt_en_dev *, unsigned int, 80 - struct bnxt_ulp_ops *, void *); 81 - int (*bnxt_unregister_device)(struct bnxt_en_dev *, unsigned int); 82 - int (*bnxt_request_msix)(struct bnxt_en_dev *, unsigned int, 83 - struct bnxt_msix_entry *, int); 84 - int (*bnxt_free_msix)(struct bnxt_en_dev *, unsigned int); 85 - int (*bnxt_send_fw_msg)(struct bnxt_en_dev *, unsigned int, 86 - struct bnxt_fw_msg *); 87 - int (*bnxt_register_fw_async_events)(struct bnxt_en_dev *, unsigned int, 88 - unsigned long *, u16); 89 - }; 90 - 91 - static inline bool bnxt_ulp_registered(struct bnxt_en_dev *edev, int ulp_id) 87 + static inline bool bnxt_ulp_registered(struct bnxt_en_dev *edev) 92 88 { 93 - if (edev && rcu_access_pointer(edev->ulp_tbl[ulp_id].ulp_ops)) 89 + if (edev && edev->ulp_tbl) 94 90 return true; 95 91 return false; 96 92 } ··· 96 102 void bnxt_ulp_stop(struct bnxt *bp); 97 103 void bnxt_ulp_start(struct bnxt *bp, int err); 98 104 void bnxt_ulp_sriov_cfg(struct bnxt *bp, int num_vfs); 99 - void bnxt_ulp_shutdown(struct bnxt *bp); 100 105 void bnxt_ulp_irq_stop(struct bnxt *bp); 101 106 void bnxt_ulp_irq_restart(struct bnxt *bp, int err); 102 107 void bnxt_ulp_async_events(struct bnxt *bp, struct hwrm_async_event_cmpl *cmpl); 103 - struct bnxt_en_dev *bnxt_ulp_probe(struct net_device *dev); 104 - 108 + void bnxt_rdma_aux_device_uninit(struct bnxt *bp); 109 + void bnxt_rdma_aux_device_init(struct bnxt *bp); 110 + int bnxt_register_dev(struct bnxt_en_dev *edev, struct bnxt_ulp_ops *ulp_ops, 111 + void *handle); 112 + void bnxt_unregister_dev(struct bnxt_en_dev *edev); 113 + int bnxt_send_msg(struct bnxt_en_dev *edev, struct bnxt_fw_msg *fw_msg); 114 + int bnxt_register_async_events(struct bnxt_en_dev *edev, 115 + unsigned long *events_bmap, u16 max_id); 105 116 #endif