hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
....@@ -36,13 +36,6 @@
3636 #include "mlx5_core.h"
3737 #include "eswitch.h"
3838
39
-bool mlx5_sriov_is_enabled(struct mlx5_core_dev *dev)
40
-{
41
- struct mlx5_core_sriov *sriov = &dev->priv.sriov;
42
-
43
- return !!sriov->num_vfs;
44
-}
45
-
4639 static int sriov_restore_guids(struct mlx5_core_dev *dev, int vf)
4740 {
4841 struct mlx5_core_sriov *sriov = &dev->priv.sriov;
....@@ -81,17 +74,10 @@
8174 int err;
8275 int vf;
8376
84
- if (sriov->enabled_vfs) {
85
- mlx5_core_warn(dev,
86
- "failed to enable SRIOV on device, already enabled with %d vfs\n",
87
- sriov->enabled_vfs);
88
- return -EBUSY;
89
- }
90
-
9177 if (!MLX5_ESWITCH_MANAGER(dev))
9278 goto enable_vfs_hca;
9379
94
- err = mlx5_eswitch_enable_sriov(dev->priv.eswitch, num_vfs, SRIOV_LEGACY);
80
+ err = mlx5_eswitch_enable(dev->priv.eswitch, num_vfs);
9581 if (err) {
9682 mlx5_core_warn(dev,
9783 "failed to enable eswitch SRIOV (%d)\n", err);
....@@ -106,7 +92,6 @@
10692 continue;
10793 }
10894 sriov->vfs_ctx[vf].enabled = 1;
109
- sriov->enabled_vfs++;
11095 if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_IB) {
11196 err = sriov_restore_guids(dev, vf);
11297 if (err) {
....@@ -122,16 +107,14 @@
122107 return 0;
123108 }
124109
125
-static void mlx5_device_disable_sriov(struct mlx5_core_dev *dev)
110
+static void
111
+mlx5_device_disable_sriov(struct mlx5_core_dev *dev, int num_vfs, bool clear_vf)
126112 {
127113 struct mlx5_core_sriov *sriov = &dev->priv.sriov;
128114 int err;
129115 int vf;
130116
131
- if (!sriov->enabled_vfs)
132
- goto out;
133
-
134
- for (vf = 0; vf < sriov->num_vfs; vf++) {
117
+ for (vf = num_vfs - 1; vf >= 0; vf--) {
135118 if (!sriov->vfs_ctx[vf].enabled)
136119 continue;
137120 err = mlx5_core_disable_hca(dev, vf + 1);
....@@ -140,44 +123,19 @@
140123 continue;
141124 }
142125 sriov->vfs_ctx[vf].enabled = 0;
143
- sriov->enabled_vfs--;
144126 }
145127
146
-out:
147128 if (MLX5_ESWITCH_MANAGER(dev))
148
- mlx5_eswitch_disable_sriov(dev->priv.eswitch);
129
+ mlx5_eswitch_disable(dev->priv.eswitch, clear_vf);
149130
150
- if (mlx5_wait_for_vf_pages(dev))
131
+ if (mlx5_wait_for_pages(dev, &dev->priv.vfs_pages))
151132 mlx5_core_warn(dev, "timeout reclaiming VFs pages\n");
152
-}
153
-
154
-static int mlx5_pci_enable_sriov(struct pci_dev *pdev, int num_vfs)
155
-{
156
- struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
157
- int err = 0;
158
-
159
- if (pci_num_vf(pdev)) {
160
- mlx5_core_warn(dev, "Unable to enable pci sriov, already enabled\n");
161
- return -EBUSY;
162
- }
163
-
164
- err = pci_enable_sriov(pdev, num_vfs);
165
- if (err)
166
- mlx5_core_warn(dev, "pci_enable_sriov failed : %d\n", err);
167
-
168
- return err;
169
-}
170
-
171
-static void mlx5_pci_disable_sriov(struct pci_dev *pdev)
172
-{
173
- pci_disable_sriov(pdev);
174133 }
175134
176135 static int mlx5_sriov_enable(struct pci_dev *pdev, int num_vfs)
177136 {
178137 struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
179
- struct mlx5_core_sriov *sriov = &dev->priv.sriov;
180
- int err = 0;
138
+ int err;
181139
182140 err = mlx5_device_enable_sriov(dev, num_vfs);
183141 if (err) {
....@@ -185,64 +143,48 @@
185143 return err;
186144 }
187145
188
- err = mlx5_pci_enable_sriov(pdev, num_vfs);
146
+ err = pci_enable_sriov(pdev, num_vfs);
189147 if (err) {
190
- mlx5_core_warn(dev, "mlx5_pci_enable_sriov failed : %d\n", err);
191
- mlx5_device_disable_sriov(dev);
192
- return err;
148
+ mlx5_core_warn(dev, "pci_enable_sriov failed : %d\n", err);
149
+ mlx5_device_disable_sriov(dev, num_vfs, true);
193150 }
194
-
195
- sriov->num_vfs = num_vfs;
196
-
197
- return 0;
151
+ return err;
198152 }
199153
200154 static void mlx5_sriov_disable(struct pci_dev *pdev)
201155 {
202156 struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
203
- struct mlx5_core_sriov *sriov = &dev->priv.sriov;
157
+ int num_vfs = pci_num_vf(dev->pdev);
204158
205
- mlx5_pci_disable_sriov(pdev);
206
- mlx5_device_disable_sriov(dev);
207
- sriov->num_vfs = 0;
159
+ pci_disable_sriov(pdev);
160
+ mlx5_device_disable_sriov(dev, num_vfs, true);
208161 }
209162
210163 int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs)
211164 {
212165 struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
166
+ struct mlx5_core_sriov *sriov = &dev->priv.sriov;
213167 int err = 0;
214168
215169 mlx5_core_dbg(dev, "requested num_vfs %d\n", num_vfs);
216
- if (!mlx5_core_is_pf(dev))
217
- return -EPERM;
218170
219
- if (num_vfs) {
220
- int ret;
221
-
222
- ret = mlx5_lag_forbid(dev);
223
- if (ret && (ret != -ENODEV))
224
- return ret;
225
- }
226
-
227
- if (num_vfs) {
171
+ if (num_vfs)
228172 err = mlx5_sriov_enable(pdev, num_vfs);
229
- } else {
173
+ else
230174 mlx5_sriov_disable(pdev);
231
- mlx5_lag_allow(dev);
232
- }
233175
176
+ if (!err)
177
+ sriov->num_vfs = num_vfs;
234178 return err ? err : num_vfs;
235179 }
236180
237181 int mlx5_sriov_attach(struct mlx5_core_dev *dev)
238182 {
239
- struct mlx5_core_sriov *sriov = &dev->priv.sriov;
240
-
241
- if (!mlx5_core_is_pf(dev) || !sriov->num_vfs)
183
+ if (!mlx5_core_is_pf(dev) || !pci_num_vf(dev->pdev))
242184 return 0;
243185
244186 /* If sriov VFs exist in PCI level, enable them in device level */
245
- return mlx5_device_enable_sriov(dev, sriov->num_vfs);
187
+ return mlx5_device_enable_sriov(dev, pci_num_vf(dev->pdev));
246188 }
247189
248190 void mlx5_sriov_detach(struct mlx5_core_dev *dev)
....@@ -250,7 +192,30 @@
250192 if (!mlx5_core_is_pf(dev))
251193 return;
252194
253
- mlx5_device_disable_sriov(dev);
195
+ mlx5_device_disable_sriov(dev, pci_num_vf(dev->pdev), false);
196
+}
197
+
198
+static u16 mlx5_get_max_vfs(struct mlx5_core_dev *dev)
199
+{
200
+ u16 host_total_vfs;
201
+ const u32 *out;
202
+
203
+ if (mlx5_core_is_ecpf_esw_manager(dev)) {
204
+ out = mlx5_esw_query_functions(dev);
205
+
206
+ /* Old FW doesn't support getting total_vfs from esw func
207
+ * but supports getting it from pci_sriov.
208
+ */
209
+ if (IS_ERR(out))
210
+ goto done;
211
+ host_total_vfs = MLX5_GET(query_esw_functions_out, out,
212
+ host_params_context.host_total_vfs);
213
+ kvfree(out);
214
+ return host_total_vfs;
215
+ }
216
+
217
+done:
218
+ return pci_sriov_get_totalvfs(dev->pdev);
254219 }
255220
256221 int mlx5_sriov_init(struct mlx5_core_dev *dev)
....@@ -263,6 +228,7 @@
263228 return 0;
264229
265230 total_vfs = pci_sriov_get_totalvfs(pdev);
231
+ sriov->max_vfs = mlx5_get_max_vfs(dev);
266232 sriov->num_vfs = pci_num_vf(pdev);
267233 sriov->vfs_ctx = kcalloc(total_vfs, sizeof(*sriov->vfs_ctx), GFP_KERNEL);
268234 if (!sriov->vfs_ctx)