Merge branches 'pm-devfreq', 'pm-qos', 'pm-tools' and 'pm-docs'
[linux-2.6-block.git] / drivers / net / ethernet / mellanox / mlx5 / core / lag / debugfs.c
CommitLineData
7f46a0b7
MB
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
3
4#include "lag.h"
5
6static char *get_str_mode_type(struct mlx5_lag *ldev)
7{
94db3317
EC
8 switch (ldev->mode) {
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";
14 }
7f46a0b7
MB
15
16 return NULL;
17}
18
19static int type_show(struct seq_file *file, void *priv)
20{
21 struct mlx5_core_dev *dev = file->private;
22 struct mlx5_lag *ldev;
23 char *mode = NULL;
24
25 ldev = dev->priv.lag;
26 mutex_lock(&ldev->lock);
27 if (__mlx5_lag_is_active(ldev))
28 mode = get_str_mode_type(ldev);
29 mutex_unlock(&ldev->lock);
30 if (!mode)
31 return -EINVAL;
32 seq_printf(file, "%s\n", mode);
33
34 return 0;
35}
36
37static int port_sel_mode_show(struct seq_file *file, void *priv)
38{
39 struct mlx5_core_dev *dev = file->private;
40 struct mlx5_lag *ldev;
41 int ret = 0;
42 char *mode;
43
44 ldev = dev->priv.lag;
45 mutex_lock(&ldev->lock);
46 if (__mlx5_lag_is_active(ldev))
1afbd1e2 47 mode = mlx5_get_str_port_sel_mode(ldev->mode, ldev->mode_flags);
7f46a0b7
MB
48 else
49 ret = -EINVAL;
50 mutex_unlock(&ldev->lock);
94db3317 51 if (ret)
7f46a0b7
MB
52 return ret;
53
54 seq_printf(file, "%s\n", mode);
55 return 0;
56}
57
58static int state_show(struct seq_file *file, void *priv)
59{
60 struct mlx5_core_dev *dev = file->private;
61 struct mlx5_lag *ldev;
62 bool active;
63
64 ldev = dev->priv.lag;
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");
69 return 0;
70}
71
72static int flags_show(struct seq_file *file, void *priv)
73{
74 struct mlx5_core_dev *dev = file->private;
4892bd98 75 bool fdb_sel_mode_native;
7f46a0b7
MB
76 struct mlx5_lag *ldev;
77 bool shared_fdb;
78 bool lag_active;
79
80 ldev = dev->priv.lag;
81 mutex_lock(&ldev->lock);
82 lag_active = __mlx5_lag_is_active(ldev);
4892bd98
MB
83 if (!lag_active)
84 goto unlock;
85
86 shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
87 fdb_sel_mode_native = test_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
88 &ldev->mode_flags);
7f46a0b7 89
4892bd98 90unlock:
7f46a0b7
MB
91 mutex_unlock(&ldev->lock);
92 if (!lag_active)
93 return -EINVAL;
94
95 seq_printf(file, "%s:%s\n", "shared_fdb", shared_fdb ? "on" : "off");
4892bd98
MB
96 seq_printf(file, "%s:%s\n", "fdb_selection_mode",
97 fdb_sel_mode_native ? "native" : "affinity");
7f46a0b7
MB
98 return 0;
99}
100
101static int mapping_show(struct seq_file *file, void *priv)
102{
103 struct mlx5_core_dev *dev = file->private;
104 u8 ports[MLX5_MAX_PORTS] = {};
105 struct mlx5_lag *ldev;
106 bool hash = false;
107 bool lag_active;
108 int num_ports;
109 int i;
110
111 ldev = dev->priv.lag;
112 mutex_lock(&ldev->lock);
113 lag_active = __mlx5_lag_is_active(ldev);
114 if (lag_active) {
ef9a3a4a 115 if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &ldev->mode_flags)) {
7f46a0b7
MB
116 mlx5_infer_tx_enabled(&ldev->tracker, ldev->ports, ports,
117 &num_ports);
118 hash = true;
119 } else {
120 for (i = 0; i < ldev->ports; i++)
121 ports[i] = ldev->v2p_map[i];
122 num_ports = ldev->ports;
123 }
124 }
125 mutex_unlock(&ldev->lock);
126 if (!lag_active)
127 return -EINVAL;
128
129 for (i = 0; i < num_ports; i++) {
130 if (hash)
131 seq_printf(file, "%d\n", ports[i] + 1);
132 else
133 seq_printf(file, "%d:%d\n", i + 1, ports[i]);
134 }
135
136 return 0;
137}
138
139static int members_show(struct seq_file *file, void *priv)
140{
141 struct mlx5_core_dev *dev = file->private;
142 struct mlx5_lag *ldev;
143 int i;
144
145 ldev = dev->priv.lag;
146 mutex_lock(&ldev->lock);
147 for (i = 0; i < ldev->ports; i++) {
148 if (!ldev->pf[i].dev)
149 continue;
150 seq_printf(file, "%s\n", dev_name(ldev->pf[i].dev->device));
151 }
152 mutex_unlock(&ldev->lock);
153
154 return 0;
155}
156
157DEFINE_SHOW_ATTRIBUTE(type);
158DEFINE_SHOW_ATTRIBUTE(port_sel_mode);
159DEFINE_SHOW_ATTRIBUTE(state);
160DEFINE_SHOW_ATTRIBUTE(flags);
161DEFINE_SHOW_ATTRIBUTE(mapping);
162DEFINE_SHOW_ATTRIBUTE(members);
163
164void mlx5_ldev_add_debugfs(struct mlx5_core_dev *dev)
165{
166 struct dentry *dbg;
167
168 dbg = debugfs_create_dir("lag", mlx5_debugfs_get_dev_root(dev));
169 dev->priv.dbg.lag_debugfs = dbg;
170
171 debugfs_create_file("type", 0444, dbg, dev, &type_fops);
172 debugfs_create_file("port_sel_mode", 0444, dbg, dev, &port_sel_mode_fops);
173 debugfs_create_file("state", 0444, dbg, dev, &state_fops);
174 debugfs_create_file("flags", 0444, dbg, dev, &flags_fops);
175 debugfs_create_file("mapping", 0444, dbg, dev, &mapping_fops);
176 debugfs_create_file("members", 0444, dbg, dev, &members_fops);
177}
178
179void mlx5_ldev_remove_debugfs(struct dentry *dbg)
180{
181 debugfs_remove_recursive(dbg);
182}