qlge_devlink.c (4955B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2#include "qlge.h" 3#include "qlge_devlink.h" 4 5static int qlge_fill_seg_(struct devlink_fmsg *fmsg, 6 struct mpi_coredump_segment_header *seg_header, 7 u32 *reg_data) 8{ 9 int regs_num = (seg_header->seg_size 10 - sizeof(struct mpi_coredump_segment_header)) / sizeof(u32); 11 int err; 12 int i; 13 14 err = devlink_fmsg_pair_nest_start(fmsg, seg_header->description); 15 if (err) 16 return err; 17 err = devlink_fmsg_obj_nest_start(fmsg); 18 if (err) 19 return err; 20 err = devlink_fmsg_u32_pair_put(fmsg, "segment", seg_header->seg_num); 21 if (err) 22 return err; 23 err = devlink_fmsg_arr_pair_nest_start(fmsg, "values"); 24 if (err) 25 return err; 26 for (i = 0; i < regs_num; i++) { 27 err = devlink_fmsg_u32_put(fmsg, *reg_data); 28 if (err) 29 return err; 30 reg_data++; 31 } 32 err = devlink_fmsg_obj_nest_end(fmsg); 33 if (err) 34 return err; 35 err = devlink_fmsg_arr_pair_nest_end(fmsg); 36 if (err) 37 return err; 38 err = devlink_fmsg_pair_nest_end(fmsg); 39 return err; 40} 41 42#define FILL_SEG(seg_hdr, seg_regs) \ 43 do { \ 44 err = qlge_fill_seg_(fmsg, &dump->seg_hdr, dump->seg_regs); \ 45 if (err) { \ 46 kvfree(dump); \ 47 return err; \ 48 } \ 49 } while (0) 50 51static int qlge_reporter_coredump(struct devlink_health_reporter *reporter, 52 struct devlink_fmsg *fmsg, void *priv_ctx, 53 struct netlink_ext_ack *extack) 54{ 55 int err = 0; 56 57 struct qlge_adapter *qdev = devlink_health_reporter_priv(reporter); 58 struct qlge_mpi_coredump *dump; 59 wait_queue_head_t wait; 60 61 if (!netif_running(qdev->ndev)) 62 return 0; 63 64 if (test_bit(QL_FRC_COREDUMP, &qdev->flags)) { 65 if (qlge_own_firmware(qdev)) { 66 qlge_queue_fw_error(qdev); 67 init_waitqueue_head(&wait); 68 wait_event_timeout(wait, 0, 5 * HZ); 69 } else { 70 netif_err(qdev, ifup, qdev->ndev, 71 "Force Coredump failed because this NIC function doesn't own the firmware\n"); 72 return -EPERM; 73 } 74 } 75 76 dump = kvmalloc(sizeof(*dump), GFP_KERNEL); 77 if (!dump) 78 return -ENOMEM; 79 80 err = qlge_core_dump(qdev, dump); 81 if (err) { 82 kvfree(dump); 83 return err; 84 } 85 86 qlge_soft_reset_mpi_risc(qdev); 87 88 FILL_SEG(core_regs_seg_hdr, mpi_core_regs); 89 FILL_SEG(test_logic_regs_seg_hdr, test_logic_regs); 90 FILL_SEG(rmii_regs_seg_hdr, rmii_regs); 91 FILL_SEG(fcmac1_regs_seg_hdr, fcmac1_regs); 92 FILL_SEG(fcmac2_regs_seg_hdr, fcmac2_regs); 93 FILL_SEG(fc1_mbx_regs_seg_hdr, fc1_mbx_regs); 94 FILL_SEG(ide_regs_seg_hdr, ide_regs); 95 FILL_SEG(nic1_mbx_regs_seg_hdr, nic1_mbx_regs); 96 FILL_SEG(smbus_regs_seg_hdr, smbus_regs); 97 FILL_SEG(fc2_mbx_regs_seg_hdr, fc2_mbx_regs); 98 FILL_SEG(nic2_mbx_regs_seg_hdr, nic2_mbx_regs); 99 FILL_SEG(i2c_regs_seg_hdr, i2c_regs); 100 FILL_SEG(memc_regs_seg_hdr, memc_regs); 101 FILL_SEG(pbus_regs_seg_hdr, pbus_regs); 102 FILL_SEG(mde_regs_seg_hdr, mde_regs); 103 FILL_SEG(nic_regs_seg_hdr, nic_regs); 104 FILL_SEG(nic2_regs_seg_hdr, nic2_regs); 105 FILL_SEG(xgmac1_seg_hdr, xgmac1); 106 FILL_SEG(xgmac2_seg_hdr, xgmac2); 107 FILL_SEG(code_ram_seg_hdr, code_ram); 108 FILL_SEG(memc_ram_seg_hdr, memc_ram); 109 FILL_SEG(xaui_an_hdr, serdes_xaui_an); 110 FILL_SEG(xaui_hss_pcs_hdr, serdes_xaui_hss_pcs); 111 FILL_SEG(xfi_an_hdr, serdes_xfi_an); 112 FILL_SEG(xfi_train_hdr, serdes_xfi_train); 113 FILL_SEG(xfi_hss_pcs_hdr, serdes_xfi_hss_pcs); 114 FILL_SEG(xfi_hss_tx_hdr, serdes_xfi_hss_tx); 115 FILL_SEG(xfi_hss_rx_hdr, serdes_xfi_hss_rx); 116 FILL_SEG(xfi_hss_pll_hdr, serdes_xfi_hss_pll); 117 118 err = qlge_fill_seg_(fmsg, &dump->misc_nic_seg_hdr, 119 (u32 *)&dump->misc_nic_info); 120 if (err) { 121 kvfree(dump); 122 return err; 123 } 124 125 FILL_SEG(intr_states_seg_hdr, intr_states); 126 FILL_SEG(cam_entries_seg_hdr, cam_entries); 127 FILL_SEG(nic_routing_words_seg_hdr, nic_routing_words); 128 FILL_SEG(ets_seg_hdr, ets); 129 FILL_SEG(probe_dump_seg_hdr, probe_dump); 130 FILL_SEG(routing_reg_seg_hdr, routing_regs); 131 FILL_SEG(mac_prot_reg_seg_hdr, mac_prot_regs); 132 FILL_SEG(xaui2_an_hdr, serdes2_xaui_an); 133 FILL_SEG(xaui2_hss_pcs_hdr, serdes2_xaui_hss_pcs); 134 FILL_SEG(xfi2_an_hdr, serdes2_xfi_an); 135 FILL_SEG(xfi2_train_hdr, serdes2_xfi_train); 136 FILL_SEG(xfi2_hss_pcs_hdr, serdes2_xfi_hss_pcs); 137 FILL_SEG(xfi2_hss_tx_hdr, serdes2_xfi_hss_tx); 138 FILL_SEG(xfi2_hss_rx_hdr, serdes2_xfi_hss_rx); 139 FILL_SEG(xfi2_hss_pll_hdr, serdes2_xfi_hss_pll); 140 FILL_SEG(sem_regs_seg_hdr, sem_regs); 141 142 kvfree(dump); 143 return err; 144} 145 146static const struct devlink_health_reporter_ops qlge_reporter_ops = { 147 .name = "coredump", 148 .dump = qlge_reporter_coredump, 149}; 150 151long qlge_health_create_reporters(struct qlge_adapter *priv) 152{ 153 struct devlink *devlink; 154 long err = 0; 155 156 devlink = priv_to_devlink(priv); 157 priv->reporter = 158 devlink_health_reporter_create(devlink, &qlge_reporter_ops, 159 0, priv); 160 if (IS_ERR(priv->reporter)) { 161 err = PTR_ERR(priv->reporter); 162 netdev_warn(priv->ndev, 163 "Failed to create reporter, err = %ld\n", 164 err); 165 } 166 return err; 167}