cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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}