From 47458190443bfc1355ee06edf2348c3d88142df0 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Wed, 2 Oct 2019 09:40:23 +0000 Subject: [PATCH] Read rege map from crdump scan space in mlx5core. Submitted by: kib@ MFC after: 3 days Sponsored by: Mellanox Technologies --- sys/dev/mlx5/driver.h | 2 +- sys/dev/mlx5/mlx5_core/mlx5_fwdump.c | 86 +++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 16 deletions(-) diff --git a/sys/dev/mlx5/driver.h b/sys/dev/mlx5/driver.h index 36be431da35..a1a3c7c6391 100644 --- a/sys/dev/mlx5/driver.h +++ b/sys/dev/mlx5/driver.h @@ -698,7 +698,7 @@ struct mlx5_core_dev { struct mlx5_flow_root_namespace *sniffer_rx_root_ns; struct mlx5_flow_root_namespace *sniffer_tx_root_ns; u32 num_q_counter_allocated[MLX5_INTERFACE_NUMBER]; - const struct mlx5_crspace_regmap *dump_rege; + struct mlx5_crspace_regmap *dump_rege; uint32_t *dump_data; unsigned dump_size; bool dump_valid; diff --git a/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c b/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c index 27be4d6d561..5777196b204 100644 --- a/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c +++ b/sys/dev/mlx5/mlx5_core/mlx5_fwdump.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2018, Mellanox Technologies, Ltd. All rights reserved. + * Copyright (c) 2018, 2019 Mellanox Technologies, Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -64,7 +64,10 @@ mlx5_fwdump_destroy_dd(struct mlx5_core_dev *mdev) void mlx5_fwdump_prep(struct mlx5_core_dev *mdev) { - int error; + device_t dev; + int error, vsc_addr; + unsigned i, sz; + u32 addr, in, out, next_addr; mdev->dump_data = NULL; error = mlx5_vsc_find_cap(mdev); @@ -74,25 +77,77 @@ mlx5_fwdump_prep(struct mlx5_core_dev *mdev) "mlx5_fwdump_prep failed %d\n", error); return; } - switch (pci_get_device(mdev->pdev->dev.bsddev)) { - case 0x1013: - mdev->dump_rege = mlx5_crspace_regmap_mt4115; - break; - case 0x1015: - mdev->dump_rege = mlx5_crspace_regmap_mt4117; - break; - case 0x1017: - case 0x1019: - mdev->dump_rege = mlx5_crspace_regmap_connectx5; - break; - default: - return; /* silently fail, do not prevent driver attach */ + error = mlx5_vsc_lock(mdev); + if (error != 0) + return; + error = mlx5_vsc_set_space(mdev, MLX5_VSC_DOMAIN_SCAN_CRSPACE); + if (error != 0) { + mlx5_core_warn(mdev, "VSC scan space is not supported\n"); + goto unlock_vsc; + } + dev = mdev->pdev->dev.bsddev; + vsc_addr = mdev->vsc_addr; + if (vsc_addr == 0) { + mlx5_core_warn(mdev, "Cannot read vsc, no address\n"); + goto unlock_vsc; } + + in = 0; + for (sz = 1, addr = 0;;) { + MLX5_VSC_SET(vsc_addr, &in, address, addr); + pci_write_config(dev, vsc_addr + MLX5_VSC_ADDR_OFFSET, in, 4); + error = mlx5_vsc_wait_on_flag(mdev, 1); + if (error != 0) { + mlx5_core_warn(mdev, + "Failed waiting for read complete flag, error %d\n", error); + goto unlock_vsc; + } + pci_read_config(dev, vsc_addr + MLX5_VSC_DATA_OFFSET, 4); + out = pci_read_config(dev, vsc_addr + MLX5_VSC_ADDR_OFFSET, 4); + next_addr = MLX5_VSC_GET(vsc_addr, &out, address); + if (next_addr == 0 || next_addr == addr) + break; + if (next_addr != addr + 4) + sz++; + addr = next_addr; + } + mdev->dump_rege = malloc(sz * sizeof(struct mlx5_crspace_regmap), + M_MLX5_DUMP, M_WAITOK | M_ZERO); + + for (i = 0, addr = 0;;) { + MPASS(i < sz); + mdev->dump_rege[i].cnt++; + MLX5_VSC_SET(vsc_addr, &in, address, addr); + pci_write_config(dev, vsc_addr + MLX5_VSC_ADDR_OFFSET, in, 4); + error = mlx5_vsc_wait_on_flag(mdev, 1); + if (error != 0) { + mlx5_core_warn(mdev, + "Failed waiting for read complete flag, error %d\n", error); + free(mdev->dump_rege, M_MLX5_DUMP); + mdev->dump_rege = NULL; + goto unlock_vsc; + } + pci_read_config(dev, vsc_addr + MLX5_VSC_DATA_OFFSET, 4); + out = pci_read_config(dev, vsc_addr + MLX5_VSC_ADDR_OFFSET, 4); + next_addr = MLX5_VSC_GET(vsc_addr, &out, address); + if (next_addr == 0 || next_addr == addr) + break; + if (next_addr != addr + 4) + mdev->dump_rege[++i].addr = next_addr; + addr = next_addr; + } + KASSERT(i + 1 == sz, + ("inconsistent hw crspace reads: sz %u i %u addr %#lx", + sz, i, (unsigned long)addr)); + mdev->dump_size = mlx5_fwdump_getsize(mdev->dump_rege); mdev->dump_data = malloc(mdev->dump_size * sizeof(uint32_t), M_MLX5_DUMP, M_WAITOK | M_ZERO); mdev->dump_valid = false; mdev->dump_copyout = false; + +unlock_vsc: + mlx5_vsc_unlock(mdev); } void @@ -145,6 +200,7 @@ mlx5_fwdump_clean(struct mlx5_core_dev *mdev) msleep(&mdev->dump_copyout, &mdev->dump_lock, 0, "mlx5fwc", 0); mlx5_fwdump_destroy_dd(mdev); mtx_unlock(&mdev->dump_lock); + free(mdev->dump_rege, M_MLX5_DUMP); } static int -- 2.45.0