1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
6 static char *get_str_mode_type(struct mlx5_lag *ldev)
9 case MLX5_LAG_MODE_ROCE: return "roce";
10 case MLX5_LAG_MODE_SRIOV: return "switchdev";
11 case MLX5_LAG_MODE_MULTIPATH: return "multipath";
12 case MLX5_LAG_MODE_MPESW: return "multiport_eswitch";
13 default: return "invalid";
19 static int type_show(struct seq_file *file, void *priv)
21 struct mlx5_core_dev *dev = file->private;
22 struct mlx5_lag *ldev;
26 mutex_lock(&ldev->lock);
27 if (__mlx5_lag_is_active(ldev))
28 mode = get_str_mode_type(ldev);
29 mutex_unlock(&ldev->lock);
32 seq_printf(file, "%s\n", mode);
37 static int port_sel_mode_show(struct seq_file *file, void *priv)
39 struct mlx5_core_dev *dev = file->private;
40 struct mlx5_lag *ldev;
45 mutex_lock(&ldev->lock);
46 if (__mlx5_lag_is_active(ldev))
47 mode = mlx5_get_str_port_sel_mode(ldev);
50 mutex_unlock(&ldev->lock);
54 seq_printf(file, "%s\n", mode);
58 static int state_show(struct seq_file *file, void *priv)
60 struct mlx5_core_dev *dev = file->private;
61 struct mlx5_lag *ldev;
65 mutex_lock(&ldev->lock);
66 active = __mlx5_lag_is_active(ldev);
67 mutex_unlock(&ldev->lock);
68 seq_printf(file, "%s\n", active ? "active" : "disabled");
72 static int flags_show(struct seq_file *file, void *priv)
74 struct mlx5_core_dev *dev = file->private;
75 struct mlx5_lag *ldev;
80 mutex_lock(&ldev->lock);
81 lag_active = __mlx5_lag_is_active(ldev);
83 shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
85 mutex_unlock(&ldev->lock);
89 seq_printf(file, "%s:%s\n", "shared_fdb", shared_fdb ? "on" : "off");
93 static int mapping_show(struct seq_file *file, void *priv)
95 struct mlx5_core_dev *dev = file->private;
96 u8 ports[MLX5_MAX_PORTS] = {};
97 struct mlx5_lag *ldev;
103 ldev = dev->priv.lag;
104 mutex_lock(&ldev->lock);
105 lag_active = __mlx5_lag_is_active(ldev);
107 if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &ldev->mode_flags)) {
108 mlx5_infer_tx_enabled(&ldev->tracker, ldev->ports, ports,
112 for (i = 0; i < ldev->ports; i++)
113 ports[i] = ldev->v2p_map[i];
114 num_ports = ldev->ports;
117 mutex_unlock(&ldev->lock);
121 for (i = 0; i < num_ports; i++) {
123 seq_printf(file, "%d\n", ports[i] + 1);
125 seq_printf(file, "%d:%d\n", i + 1, ports[i]);
131 static int members_show(struct seq_file *file, void *priv)
133 struct mlx5_core_dev *dev = file->private;
134 struct mlx5_lag *ldev;
137 ldev = dev->priv.lag;
138 mutex_lock(&ldev->lock);
139 for (i = 0; i < ldev->ports; i++) {
140 if (!ldev->pf[i].dev)
142 seq_printf(file, "%s\n", dev_name(ldev->pf[i].dev->device));
144 mutex_unlock(&ldev->lock);
149 DEFINE_SHOW_ATTRIBUTE(type);
150 DEFINE_SHOW_ATTRIBUTE(port_sel_mode);
151 DEFINE_SHOW_ATTRIBUTE(state);
152 DEFINE_SHOW_ATTRIBUTE(flags);
153 DEFINE_SHOW_ATTRIBUTE(mapping);
154 DEFINE_SHOW_ATTRIBUTE(members);
156 void mlx5_ldev_add_debugfs(struct mlx5_core_dev *dev)
160 dbg = debugfs_create_dir("lag", mlx5_debugfs_get_dev_root(dev));
161 dev->priv.dbg.lag_debugfs = dbg;
163 debugfs_create_file("type", 0444, dbg, dev, &type_fops);
164 debugfs_create_file("port_sel_mode", 0444, dbg, dev, &port_sel_mode_fops);
165 debugfs_create_file("state", 0444, dbg, dev, &state_fops);
166 debugfs_create_file("flags", 0444, dbg, dev, &flags_fops);
167 debugfs_create_file("mapping", 0444, dbg, dev, &mapping_fops);
168 debugfs_create_file("members", 0444, dbg, dev, &members_fops);
171 void mlx5_ldev_remove_debugfs(struct dentry *dbg)
173 debugfs_remove_recursive(dbg);