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 'bnxt_en-updates-for-net-next'

Michael Chan says:

====================
bnxt_en: Updates for net-next

The first patch converts the sw_stats field in the completion
ring structure to a pointer. This allows the group of
completion rings using the same MSIX to share the same sw_stats
structure. Prior to this, the correct completion ring must be
used to count packets.

The next four patches remove the RTNL lock when calling the RoCE
driver for asynchronous stop and start during error recovery and
firmware reset. The RTNL ilock is replaced with a private mutex
used to synchronize RoCE register, unregister, stop, and start.

The last patch adds VF PCI IDs for the 5760X chips.

v2: Dropped patch #1 from v1. Will work with David to get that
patch in separately.
====================

Link: https://lore.kernel.org/r/20240501003056.100607-1-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+107 -61
+67 -52
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 137 137 [NETXTREME_E_VF_HV] = { "Broadcom NetXtreme-E Virtual Function for Hyper-V" }, 138 138 [NETXTREME_E_P5_VF] = { "Broadcom BCM5750X NetXtreme-E Ethernet Virtual Function" }, 139 139 [NETXTREME_E_P5_VF_HV] = { "Broadcom BCM5750X NetXtreme-E Virtual Function for Hyper-V" }, 140 + [NETXTREME_E_P7_VF] = { "Broadcom BCM5760X Virtual Function" }, 140 141 }; 141 142 142 143 static const struct pci_device_id bnxt_pci_tbl[] = { ··· 212 211 { PCI_VDEVICE(BROADCOM, 0x1807), .driver_data = NETXTREME_E_P5_VF }, 213 212 { PCI_VDEVICE(BROADCOM, 0x1808), .driver_data = NETXTREME_E_P5_VF_HV }, 214 213 { PCI_VDEVICE(BROADCOM, 0x1809), .driver_data = NETXTREME_E_P5_VF_HV }, 214 + { PCI_VDEVICE(BROADCOM, 0x1819), .driver_data = NETXTREME_E_P7_VF }, 215 215 { PCI_VDEVICE(BROADCOM, 0xd800), .driver_data = NETXTREME_S_VF }, 216 216 #endif 217 217 { 0 } ··· 296 294 return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF || 297 295 idx == NETXTREME_S_VF || idx == NETXTREME_C_VF_HV || 298 296 idx == NETXTREME_E_VF_HV || idx == NETXTREME_E_P5_VF || 299 - idx == NETXTREME_E_P5_VF_HV); 297 + idx == NETXTREME_E_P5_VF_HV || idx == NETXTREME_E_P7_VF); 300 298 } 301 299 302 300 #define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID) ··· 1813 1811 skb = bnxt_copy_skb(bnapi, data_ptr, len, mapping); 1814 1812 if (!skb) { 1815 1813 bnxt_abort_tpa(cpr, idx, agg_bufs); 1816 - cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1; 1814 + cpr->sw_stats->rx.rx_oom_discards += 1; 1817 1815 return NULL; 1818 1816 } 1819 1817 } else { ··· 1823 1821 new_data = __bnxt_alloc_rx_frag(bp, &new_mapping, GFP_ATOMIC); 1824 1822 if (!new_data) { 1825 1823 bnxt_abort_tpa(cpr, idx, agg_bufs); 1826 - cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1; 1824 + cpr->sw_stats->rx.rx_oom_discards += 1; 1827 1825 return NULL; 1828 1826 } 1829 1827 ··· 1839 1837 if (!skb) { 1840 1838 skb_free_frag(data); 1841 1839 bnxt_abort_tpa(cpr, idx, agg_bufs); 1842 - cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1; 1840 + cpr->sw_stats->rx.rx_oom_discards += 1; 1843 1841 return NULL; 1844 1842 } 1845 1843 skb_reserve(skb, bp->rx_offset); ··· 1850 1848 skb = bnxt_rx_agg_pages_skb(bp, cpr, skb, idx, agg_bufs, true); 1851 1849 if (!skb) { 1852 1850 /* Page reuse already handled by bnxt_rx_pages(). */ 1853 - cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1; 1851 + cpr->sw_stats->rx.rx_oom_discards += 1; 1854 1852 return NULL; 1855 1853 } 1856 1854 } ··· 2108 2106 2109 2107 rc = -EIO; 2110 2108 if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) { 2111 - bnapi->cp_ring.sw_stats.rx.rx_buf_errors++; 2109 + bnapi->cp_ring.sw_stats->rx.rx_buf_errors++; 2112 2110 if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS) && 2113 2111 !(bp->fw_cap & BNXT_FW_CAP_RING_MONITOR)) { 2114 2112 netdev_warn_once(bp->dev, "RX buffer error %x\n", ··· 2224 2222 } else { 2225 2223 if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L4_CS_ERR_BITS) { 2226 2224 if (dev->features & NETIF_F_RXCSUM) 2227 - bnapi->cp_ring.sw_stats.rx.rx_l4_csum_errors++; 2225 + bnapi->cp_ring.sw_stats->rx.rx_l4_csum_errors++; 2228 2226 } 2229 2227 } 2230 2228 ··· 2261 2259 return rc; 2262 2260 2263 2261 oom_next_rx: 2264 - cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1; 2262 + cpr->sw_stats->rx.rx_oom_discards += 1; 2265 2263 rc = -ENOMEM; 2266 2264 goto next_rx; 2267 2265 } ··· 2310 2308 } 2311 2309 rc = bnxt_rx_pkt(bp, cpr, raw_cons, event); 2312 2310 if (rc && rc != -EBUSY) 2313 - cpr->bnapi->cp_ring.sw_stats.rx.rx_netpoll_discards += 1; 2311 + cpr->sw_stats->rx.rx_netpoll_discards += 1; 2314 2312 return rc; 2315 2313 } 2316 2314 ··· 3953 3951 if (rc) 3954 3952 return rc; 3955 3953 cpr2->bnapi = bnapi; 3954 + cpr2->sw_stats = cpr->sw_stats; 3956 3955 cpr2->cp_idx = k; 3957 3956 if (!k && rx) { 3958 3957 bp->rx_ring[i].rx_cpr = cpr2; ··· 4795 4792 struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; 4796 4793 4797 4794 bnxt_free_stats_mem(bp, &cpr->stats); 4795 + 4796 + kfree(cpr->sw_stats); 4797 + cpr->sw_stats = NULL; 4798 4798 } 4799 4799 } 4800 4800 ··· 4811 4805 for (i = 0; i < bp->cp_nr_rings; i++) { 4812 4806 struct bnxt_napi *bnapi = bp->bnapi[i]; 4813 4807 struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; 4808 + 4809 + cpr->sw_stats = kzalloc(sizeof(*cpr->sw_stats), GFP_KERNEL); 4810 + if (!cpr->sw_stats) 4811 + return -ENOMEM; 4814 4812 4815 4813 cpr->stats.len = size; 4816 4814 rc = bnxt_alloc_stats_mem(bp, &cpr->stats, !i); ··· 10821 10811 10822 10812 cpr = &bnapi->cp_ring; 10823 10813 if (bnapi->tx_fault) 10824 - cpr->sw_stats.tx.tx_resets++; 10814 + cpr->sw_stats->tx.tx_resets++; 10825 10815 if (bnapi->in_reset) 10826 - cpr->sw_stats.rx.rx_resets++; 10816 + cpr->sw_stats->rx.rx_resets++; 10827 10817 napi_disable(&bnapi->napi); 10828 10818 if (bnapi->rx_ring) 10829 10819 cancel_work_sync(&cpr->dim.work); ··· 11558 11548 if (fw_reset) { 11559 11549 set_bit(BNXT_STATE_FW_RESET_DET, &bp->state); 11560 11550 if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) 11561 - bnxt_ulp_stop(bp); 11551 + bnxt_ulp_irq_stop(bp); 11562 11552 bnxt_free_ctx_mem(bp); 11563 11553 bnxt_dcb_free(bp); 11564 11554 rc = bnxt_fw_init_one(bp); ··· 12113 12103 bnxt_hwrm_if_change(bp, false); 12114 12104 } else { 12115 12105 if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) { 12116 - if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { 12117 - bnxt_ulp_start(bp, 0); 12118 - bnxt_reenable_sriov(bp); 12119 - } 12106 + if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) 12107 + bnxt_queue_sp_work(bp, 12108 + BNXT_RESTART_ULP_SP_EVENT); 12120 12109 } 12121 12110 } 12122 12111 ··· 12347 12338 stats->tx_dropped += BNXT_GET_RING_STATS64(sw, tx_error_pkts); 12348 12339 12349 12340 stats->rx_dropped += 12350 - cpr->sw_stats.rx.rx_netpoll_discards + 12351 - cpr->sw_stats.rx.rx_oom_discards; 12341 + cpr->sw_stats->rx.rx_netpoll_discards + 12342 + cpr->sw_stats->rx.rx_oom_discards; 12352 12343 } 12353 12344 } 12354 12345 ··· 12415 12406 struct bnxt_total_ring_err_stats *stats, 12416 12407 struct bnxt_cp_ring_info *cpr) 12417 12408 { 12418 - struct bnxt_sw_stats *sw_stats = &cpr->sw_stats; 12409 + struct bnxt_sw_stats *sw_stats = cpr->sw_stats; 12419 12410 u64 *hw_stats = cpr->stats.sw_stats; 12420 12411 12421 12412 stats->rx_total_l4_csum_errors += sw_stats->rx.rx_l4_csum_errors; ··· 13090 13081 if (!silent) 13091 13082 bnxt_dbg_dump_states(bp); 13092 13083 if (netif_running(bp->dev)) { 13093 - int rc; 13094 - 13095 - if (silent) { 13096 - bnxt_close_nic(bp, false, false); 13097 - bnxt_open_nic(bp, false, false); 13098 - } else { 13099 - bnxt_ulp_stop(bp); 13100 - bnxt_close_nic(bp, true, false); 13101 - rc = bnxt_open_nic(bp, true, false); 13102 - bnxt_ulp_start(bp, rc); 13103 - } 13084 + bnxt_close_nic(bp, !silent, false); 13085 + bnxt_open_nic(bp, !silent, false); 13104 13086 } 13105 13087 } 13106 13088 ··· 13249 13249 rxr->bnapi->in_reset = false; 13250 13250 bnxt_alloc_one_rx_ring(bp, i); 13251 13251 cpr = &rxr->bnapi->cp_ring; 13252 - cpr->sw_stats.rx.rx_resets++; 13252 + cpr->sw_stats->rx.rx_resets++; 13253 13253 if (bp->flags & BNXT_FLAG_AGG_RINGS) 13254 13254 bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); 13255 13255 bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod); ··· 13271 13271 13272 13272 static void bnxt_fw_reset_close(struct bnxt *bp) 13273 13273 { 13274 - bnxt_ulp_stop(bp); 13275 13274 /* When firmware is in fatal state, quiesce device and disable 13276 13275 * bus master to prevent any potential bad DMAs before freeing 13277 13276 * kernel memory. ··· 13351 13352 { 13352 13353 netdev_warn(bp->dev, "Detected firmware fatal condition, initiating reset\n"); 13353 13354 set_bit(BNXT_STATE_FW_FATAL_COND, &bp->state); 13355 + bnxt_ulp_stop(bp); 13354 13356 bnxt_rtnl_lock_sp(bp); 13355 13357 bnxt_force_fw_reset(bp); 13356 13358 bnxt_rtnl_unlock_sp(bp); ··· 13383 13383 13384 13384 void bnxt_fw_reset(struct bnxt *bp) 13385 13385 { 13386 + bnxt_ulp_stop(bp); 13386 13387 bnxt_rtnl_lock_sp(bp); 13387 13388 if (test_bit(BNXT_STATE_OPEN, &bp->state) && 13388 13389 !test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { ··· 13462 13461 bnxt_dbg_hwrm_ring_info_get(bp, 13463 13462 DBG_RING_INFO_GET_REQ_RING_TYPE_L2_CMPL, 13464 13463 fw_ring_id, &val[0], &val[1]); 13465 - cpr->sw_stats.cmn.missed_irqs++; 13464 + cpr->sw_stats->cmn.missed_irqs++; 13466 13465 } 13467 13466 } 13468 13467 } ··· 13508 13507 hwrm_req_send(bp, req); 13509 13508 } 13510 13509 13510 + static void bnxt_ulp_restart(struct bnxt *bp) 13511 + { 13512 + bnxt_ulp_stop(bp); 13513 + bnxt_ulp_start(bp, 0); 13514 + } 13515 + 13511 13516 static void bnxt_sp_task(struct work_struct *work) 13512 13517 { 13513 13518 struct bnxt *bp = container_of(work, struct bnxt, sp_task); ··· 13523 13516 if (!test_bit(BNXT_STATE_OPEN, &bp->state)) { 13524 13517 clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); 13525 13518 return; 13519 + } 13520 + 13521 + if (test_and_clear_bit(BNXT_RESTART_ULP_SP_EVENT, &bp->sp_event)) { 13522 + bnxt_ulp_restart(bp); 13523 + bnxt_reenable_sriov(bp); 13526 13524 } 13527 13525 13528 13526 if (test_and_clear_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event)) ··· 13986 13974 static void bnxt_fw_reset_abort(struct bnxt *bp, int rc) 13987 13975 { 13988 13976 clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); 13989 - if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF) { 13990 - bnxt_ulp_start(bp, rc); 13977 + if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF) 13991 13978 bnxt_dl_health_fw_status_update(bp, false); 13992 - } 13993 13979 bp->fw_reset_state = 0; 13994 13980 dev_close(bp->dev); 13995 13981 } ··· 14018 14008 bp->fw_reset_state = 0; 14019 14009 netdev_err(bp->dev, "Firmware reset aborted, bnxt_get_registered_vfs() returns %d\n", 14020 14010 n); 14021 - return; 14011 + goto ulp_start; 14022 14012 } 14023 14013 bnxt_queue_fw_reset_work(bp, HZ / 10); 14024 14014 return; ··· 14028 14018 if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) { 14029 14019 bnxt_fw_reset_abort(bp, rc); 14030 14020 rtnl_unlock(); 14031 - return; 14021 + goto ulp_start; 14032 14022 } 14033 14023 bnxt_fw_reset_close(bp); 14034 14024 if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { ··· 14121 14111 netdev_err(bp->dev, "bnxt_open() failed during FW reset\n"); 14122 14112 bnxt_fw_reset_abort(bp, rc); 14123 14113 rtnl_unlock(); 14124 - return; 14114 + goto ulp_start; 14125 14115 } 14126 14116 14127 14117 if ((bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) && ··· 14133 14123 /* Make sure fw_reset_state is 0 before clearing the flag */ 14134 14124 smp_mb__before_atomic(); 14135 14125 clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); 14136 - bnxt_ulp_start(bp, 0); 14137 - bnxt_reenable_sriov(bp); 14138 - bnxt_vf_reps_alloc(bp); 14139 - bnxt_vf_reps_open(bp); 14140 14126 bnxt_ptp_reapply_pps(bp); 14141 14127 clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state); 14142 14128 if (test_and_clear_bit(BNXT_STATE_RECOVER, &bp->state)) { 14143 14129 bnxt_dl_health_fw_recovery_done(bp); 14144 14130 bnxt_dl_health_fw_status_update(bp, true); 14145 14131 } 14132 + rtnl_unlock(); 14133 + bnxt_ulp_start(bp, 0); 14134 + bnxt_reenable_sriov(bp); 14135 + rtnl_lock(); 14136 + bnxt_vf_reps_alloc(bp); 14137 + bnxt_vf_reps_open(bp); 14146 14138 rtnl_unlock(); 14147 14139 break; 14148 14140 } ··· 14161 14149 rtnl_lock(); 14162 14150 bnxt_fw_reset_abort(bp, rc); 14163 14151 rtnl_unlock(); 14152 + ulp_start: 14153 + bnxt_ulp_start(bp, rc); 14164 14154 } 14165 14155 14166 14156 static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev) ··· 14783 14769 stats->bytes += BNXT_GET_RING_STATS64(sw, rx_mcast_bytes); 14784 14770 stats->bytes += BNXT_GET_RING_STATS64(sw, rx_bcast_bytes); 14785 14771 14786 - stats->alloc_fail = cpr->sw_stats.rx.rx_oom_discards; 14772 + stats->alloc_fail = cpr->sw_stats->rx.rx_oom_discards; 14787 14773 } 14788 14774 14789 14775 static void bnxt_get_queue_stats_tx(struct net_device *dev, int i, ··· 15549 15535 struct bnxt *bp = netdev_priv(dev); 15550 15536 int rc = 0; 15551 15537 15552 - rtnl_lock(); 15553 15538 bnxt_ulp_stop(bp); 15539 + 15540 + rtnl_lock(); 15554 15541 if (netif_running(dev)) { 15555 15542 netif_device_detach(dev); 15556 15543 rc = bnxt_close(dev); ··· 15606 15591 } 15607 15592 15608 15593 resume_exit: 15594 + rtnl_unlock(); 15609 15595 bnxt_ulp_start(bp, rc); 15610 15596 if (!rc) 15611 15597 bnxt_reenable_sriov(bp); 15612 - rtnl_unlock(); 15613 15598 return rc; 15614 15599 } 15615 15600 ··· 15639 15624 15640 15625 netdev_info(netdev, "PCI I/O error detected\n"); 15641 15626 15627 + bnxt_ulp_stop(bp); 15628 + 15642 15629 rtnl_lock(); 15643 15630 netif_device_detach(netdev); 15644 - 15645 - bnxt_ulp_stop(bp); 15646 15631 15647 15632 if (test_and_set_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { 15648 15633 netdev_err(bp->dev, "Firmware reset already in progress\n"); ··· 15779 15764 if (!err && netif_running(netdev)) 15780 15765 err = bnxt_open(netdev); 15781 15766 15782 - bnxt_ulp_start(bp, err); 15783 - if (!err) { 15784 - bnxt_reenable_sriov(bp); 15767 + if (!err) 15785 15768 netif_device_attach(netdev); 15786 - } 15787 15769 15788 15770 rtnl_unlock(); 15771 + bnxt_ulp_start(bp, err); 15772 + if (!err) 15773 + bnxt_reenable_sriov(bp); 15789 15774 } 15790 15775 15791 15776 static const struct pci_error_handlers bnxt_err_handler = {
+3 -1
drivers/net/ethernet/broadcom/bnxt/bnxt.h
··· 1152 1152 struct bnxt_stats_mem stats; 1153 1153 u32 hw_stats_ctx_id; 1154 1154 1155 - struct bnxt_sw_stats sw_stats; 1155 + struct bnxt_sw_stats *sw_stats; 1156 1156 1157 1157 struct bnxt_ring_struct cp_ring_struct; 1158 1158 ··· 2013 2013 NETXTREME_E_VF_HV, 2014 2014 NETXTREME_E_P5_VF, 2015 2015 NETXTREME_E_P5_VF_HV, 2016 + NETXTREME_E_P7_VF, 2016 2017 }; 2017 2018 2018 2019 struct bnxt { ··· 2441 2440 #define BNXT_LINK_CFG_CHANGE_SP_EVENT 21 2442 2441 #define BNXT_THERMAL_THRESHOLD_SP_EVENT 22 2443 2442 #define BNXT_FW_ECHO_REQUEST_SP_EVENT 23 2443 + #define BNXT_RESTART_ULP_SP_EVENT 24 2444 2444 2445 2445 struct delayed_work fw_reset_task; 2446 2446 int fw_reset_state;
+5 -2
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
··· 437 437 438 438 switch (action) { 439 439 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: { 440 + bnxt_ulp_stop(bp); 440 441 rtnl_lock(); 441 442 if (bnxt_sriov_cfg(bp)) { 442 443 NL_SET_ERR_MSG_MOD(extack, 443 444 "reload is unsupported while VFs are allocated or being configured"); 444 445 rtnl_unlock(); 446 + bnxt_ulp_start(bp, 0); 445 447 return -EOPNOTSUPP; 446 448 } 447 449 if (bp->dev->reg_state == NETREG_UNREGISTERED) { 448 450 rtnl_unlock(); 451 + bnxt_ulp_start(bp, 0); 449 452 return -ENODEV; 450 453 } 451 - bnxt_ulp_stop(bp); 452 454 if (netif_running(bp->dev)) 453 455 bnxt_close_nic(bp, true, true); 454 456 bnxt_vf_reps_free(bp); ··· 518 516 bnxt_vf_reps_alloc(bp); 519 517 if (netif_running(bp->dev)) 520 518 rc = bnxt_open_nic(bp, true, true); 521 - bnxt_ulp_start(bp, rc); 522 519 if (!rc) { 523 520 bnxt_reenable_sriov(bp); 524 521 bnxt_ptp_reapply_pps(bp); ··· 571 570 dev_close(bp->dev); 572 571 } 573 572 rtnl_unlock(); 573 + if (action == DEVLINK_RELOAD_ACTION_DRIVER_REINIT) 574 + bnxt_ulp_start(bp, rc); 574 575 return rc; 575 576 } 576 577
+10 -5
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
··· 631 631 buf[j] = sw_stats[k]; 632 632 633 633 skip_tpa_ring_stats: 634 - sw = (u64 *)&cpr->sw_stats.rx; 634 + sw = (u64 *)&cpr->sw_stats->rx; 635 635 if (is_rx_ring(bp, i)) { 636 636 for (k = 0; k < NUM_RING_RX_SW_STATS; j++, k++) 637 637 buf[j] = sw[k]; 638 638 } 639 639 640 - sw = (u64 *)&cpr->sw_stats.cmn; 640 + sw = (u64 *)&cpr->sw_stats->cmn; 641 641 for (k = 0; k < NUM_RING_CMN_SW_STATS; j++, k++) 642 642 buf[j] = sw[k]; 643 643 } ··· 4820 4820 4821 4821 if (!bp->num_tests || !BNXT_PF(bp)) 4822 4822 return; 4823 + 4824 + if (etest->flags & ETH_TEST_FL_OFFLINE && 4825 + bnxt_ulp_registered(bp->edev)) { 4826 + etest->flags |= ETH_TEST_FL_FAILED; 4827 + netdev_warn(dev, "Offline tests cannot be run with RoCE driver loaded\n"); 4828 + return; 4829 + } 4830 + 4823 4831 memset(buf, 0, sizeof(u64) * bp->num_tests); 4824 4832 if (!netif_running(dev)) { 4825 4833 etest->flags |= ETH_TEST_FL_FAILED; ··· 4858 4850 if (!offline) { 4859 4851 bnxt_run_fw_tests(bp, test_mask, &test_results); 4860 4852 } else { 4861 - bnxt_ulp_stop(bp); 4862 4853 bnxt_close_nic(bp, true, false); 4863 4854 bnxt_run_fw_tests(bp, test_mask, &test_results); 4864 4855 ··· 4868 4861 if (rc) { 4869 4862 bnxt_hwrm_mac_loopback(bp, false); 4870 4863 etest->flags |= ETH_TEST_FL_FAILED; 4871 - bnxt_ulp_start(bp, rc); 4872 4864 return; 4873 4865 } 4874 4866 if (bnxt_run_loopback(bp)) ··· 4894 4888 bnxt_hwrm_phy_loopback(bp, false, false); 4895 4889 bnxt_half_close_nic(bp); 4896 4890 rc = bnxt_open_nic(bp, true, true); 4897 - bnxt_ulp_start(bp, rc); 4898 4891 } 4899 4892 if (rc || bnxt_test_irq(bp)) { 4900 4893 buf[BNXT_IRQ_TEST_IDX] = 1;
+19 -1
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
··· 113 113 int rc = 0; 114 114 115 115 rtnl_lock(); 116 + mutex_lock(&edev->en_dev_lock); 116 117 if (!bp->irq_tbl) { 117 118 rc = -ENODEV; 118 119 goto exit; ··· 137 136 bnxt_fill_msix_vecs(bp, bp->edev->msix_entries); 138 137 edev->flags |= BNXT_EN_FLAG_MSIX_REQUESTED; 139 138 exit: 139 + mutex_unlock(&edev->en_dev_lock); 140 140 rtnl_unlock(); 141 141 return rc; 142 142 } ··· 152 150 153 151 ulp = edev->ulp_tbl; 154 152 rtnl_lock(); 153 + mutex_lock(&edev->en_dev_lock); 155 154 if (ulp->msix_requested) 156 155 edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED; 157 156 edev->ulp_tbl->msix_requested = 0; ··· 168 165 msleep(100); 169 166 i++; 170 167 } 168 + mutex_unlock(&edev->en_dev_lock); 171 169 rtnl_unlock(); 172 170 return; 173 171 } ··· 227 223 if (!edev) 228 224 return; 229 225 226 + mutex_lock(&edev->en_dev_lock); 227 + if (!bnxt_ulp_registered(edev)) { 228 + mutex_unlock(&edev->en_dev_lock); 229 + return; 230 + } 231 + 230 232 edev->flags |= BNXT_EN_FLAG_ULP_STOPPED; 231 233 if (aux_priv) { 232 234 struct auxiliary_device *adev; ··· 247 237 adrv->suspend(adev, pm); 248 238 } 249 239 } 240 + mutex_unlock(&edev->en_dev_lock); 250 241 } 251 242 252 243 void bnxt_ulp_start(struct bnxt *bp, int err) ··· 262 251 263 252 if (err) 264 253 return; 254 + 255 + mutex_lock(&edev->en_dev_lock); 256 + if (!bnxt_ulp_registered(edev)) { 257 + mutex_unlock(&edev->en_dev_lock); 258 + return; 259 + } 265 260 266 261 if (edev->ulp_tbl->msix_requested) 267 262 bnxt_fill_msix_vecs(bp, edev->msix_entries); ··· 284 267 adrv->resume(adev); 285 268 } 286 269 } 287 - 270 + mutex_unlock(&edev->en_dev_lock); 288 271 } 289 272 290 273 void bnxt_ulp_irq_stop(struct bnxt *bp) ··· 400 383 edev->l2_db_size = bp->db_size; 401 384 edev->l2_db_size_nc = bp->db_size; 402 385 edev->l2_db_offset = bp->db_offset; 386 + mutex_init(&edev->en_dev_lock); 403 387 404 388 if (bp->flags & BNXT_FLAG_ROCEV1_CAP) 405 389 edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP;
+3
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h
··· 88 88 89 89 u16 ulp_num_msix_vec; 90 90 u16 ulp_num_ctxs; 91 + 92 + /* serialize ulp operations */ 93 + struct mutex en_dev_lock; 91 94 }; 92 95 93 96 static inline bool bnxt_ulp_registered(struct bnxt_en_dev *edev)