4
4
#include "lib/sd.h"
5
5
#include "mlx5_core.h"
6
6
#include "lib/mlx5.h"
7
+ #include "fs_cmd.h"
7
8
#include <linux/mlx5/vport.h>
8
9
9
10
#define sd_info (__dev , format , ...) \
@@ -19,9 +20,11 @@ struct mlx5_sd {
19
20
union {
20
21
struct { /* primary */
21
22
struct mlx5_core_dev * secondaries [MLX5_SD_MAX_GROUP_SZ - 1 ];
23
+ struct mlx5_flow_table * tx_ft ;
22
24
};
23
25
struct { /* secondary */
24
26
struct mlx5_core_dev * primary_dev ;
27
+ u32 alias_obj_id ;
25
28
};
26
29
};
27
30
};
@@ -78,6 +81,21 @@ struct mlx5_core_dev *mlx5_sd_ch_ix_get_dev(struct mlx5_core_dev *primary, int c
78
81
return mlx5_sd_primary_get_peer (primary , mdev_idx );
79
82
}
80
83
84
+ static bool ft_create_alias_supported (struct mlx5_core_dev * dev )
85
+ {
86
+ u64 obj_allowed = MLX5_CAP_GEN_2_64 (dev , allowed_object_for_other_vhca_access );
87
+ u32 obj_supp = MLX5_CAP_GEN_2 (dev , cross_vhca_object_to_object_supported );
88
+
89
+ if (!(obj_supp &
90
+ MLX5_CROSS_VHCA_OBJ_TO_OBJ_SUPPORTED_LOCAL_FLOW_TABLE_ROOT_TO_REMOTE_FLOW_TABLE ))
91
+ return false;
92
+
93
+ if (!(obj_allowed & MLX5_ALLOWED_OBJ_FOR_OTHER_VHCA_ACCESS_FLOW_TABLE ))
94
+ return false;
95
+
96
+ return true;
97
+ }
98
+
81
99
static bool mlx5_sd_is_supported (struct mlx5_core_dev * dev , u8 host_buses )
82
100
{
83
101
/* Feature is currently implemented for PFs only */
@@ -88,6 +106,24 @@ static bool mlx5_sd_is_supported(struct mlx5_core_dev *dev, u8 host_buses)
88
106
if (host_buses > MLX5_SD_MAX_GROUP_SZ )
89
107
return false;
90
108
109
+ /* Disconnect secondaries from the network */
110
+ if (!MLX5_CAP_GEN (dev , eswitch_manager ))
111
+ return false;
112
+ if (!MLX5_CAP_GEN (dev , silent_mode ))
113
+ return false;
114
+
115
+ /* RX steering from primary to secondaries */
116
+ if (!MLX5_CAP_GEN (dev , cross_vhca_rqt ))
117
+ return false;
118
+ if (host_buses > MLX5_CAP_GEN_2 (dev , max_rqt_vhca_id ))
119
+ return false;
120
+
121
+ /* TX steering from secondaries to primary */
122
+ if (!ft_create_alias_supported (dev ))
123
+ return false;
124
+ if (!MLX5_CAP_FLOWTABLE_NIC_TX (dev , reset_root_to_default ))
125
+ return false;
126
+
91
127
return true;
92
128
}
93
129
@@ -227,10 +263,122 @@ static void sd_unregister(struct mlx5_core_dev *dev)
227
263
mlx5_devcom_unregister_component (sd -> devcom );
228
264
}
229
265
266
+ static int sd_cmd_set_primary (struct mlx5_core_dev * primary , u8 * alias_key )
267
+ {
268
+ struct mlx5_cmd_allow_other_vhca_access_attr allow_attr = {};
269
+ struct mlx5_sd * sd = mlx5_get_sd (primary );
270
+ struct mlx5_flow_table_attr ft_attr = {};
271
+ struct mlx5_flow_namespace * nic_ns ;
272
+ struct mlx5_flow_table * ft ;
273
+ int err ;
274
+
275
+ nic_ns = mlx5_get_flow_namespace (primary , MLX5_FLOW_NAMESPACE_EGRESS );
276
+ if (!nic_ns )
277
+ return - EOPNOTSUPP ;
278
+
279
+ ft = mlx5_create_flow_table (nic_ns , & ft_attr );
280
+ if (IS_ERR (ft )) {
281
+ err = PTR_ERR (ft );
282
+ return err ;
283
+ }
284
+ sd -> tx_ft = ft ;
285
+ memcpy (allow_attr .access_key , alias_key , ACCESS_KEY_LEN );
286
+ allow_attr .obj_type = MLX5_GENERAL_OBJECT_TYPES_FLOW_TABLE_ALIAS ;
287
+ allow_attr .obj_id = (ft -> type << FT_ID_FT_TYPE_OFFSET ) | ft -> id ;
288
+
289
+ err = mlx5_cmd_allow_other_vhca_access (primary , & allow_attr );
290
+ if (err ) {
291
+ mlx5_core_err (primary , "Failed to allow other vhca access err=%d\n" ,
292
+ err );
293
+ mlx5_destroy_flow_table (ft );
294
+ return err ;
295
+ }
296
+
297
+ return 0 ;
298
+ }
299
+
300
+ static void sd_cmd_unset_primary (struct mlx5_core_dev * primary )
301
+ {
302
+ struct mlx5_sd * sd = mlx5_get_sd (primary );
303
+
304
+ mlx5_destroy_flow_table (sd -> tx_ft );
305
+ }
306
+
307
+ static int sd_secondary_create_alias_ft (struct mlx5_core_dev * secondary ,
308
+ struct mlx5_core_dev * primary ,
309
+ struct mlx5_flow_table * ft ,
310
+ u32 * obj_id , u8 * alias_key )
311
+ {
312
+ u32 aliased_object_id = (ft -> type << FT_ID_FT_TYPE_OFFSET ) | ft -> id ;
313
+ u16 vhca_id_to_be_accessed = MLX5_CAP_GEN (primary , vhca_id );
314
+ struct mlx5_cmd_alias_obj_create_attr alias_attr = {};
315
+ int ret ;
316
+
317
+ memcpy (alias_attr .access_key , alias_key , ACCESS_KEY_LEN );
318
+ alias_attr .obj_id = aliased_object_id ;
319
+ alias_attr .obj_type = MLX5_GENERAL_OBJECT_TYPES_FLOW_TABLE_ALIAS ;
320
+ alias_attr .vhca_id = vhca_id_to_be_accessed ;
321
+ ret = mlx5_cmd_alias_obj_create (secondary , & alias_attr , obj_id );
322
+ if (ret ) {
323
+ mlx5_core_err (secondary , "Failed to create alias object err=%d\n" ,
324
+ ret );
325
+ return ret ;
326
+ }
327
+
328
+ return 0 ;
329
+ }
330
+
331
+ static void sd_secondary_destroy_alias_ft (struct mlx5_core_dev * secondary )
332
+ {
333
+ struct mlx5_sd * sd = mlx5_get_sd (secondary );
334
+
335
+ mlx5_cmd_alias_obj_destroy (secondary , sd -> alias_obj_id ,
336
+ MLX5_GENERAL_OBJECT_TYPES_FLOW_TABLE_ALIAS );
337
+ }
338
+
339
+ static int sd_cmd_set_secondary (struct mlx5_core_dev * secondary ,
340
+ struct mlx5_core_dev * primary ,
341
+ u8 * alias_key )
342
+ {
343
+ struct mlx5_sd * primary_sd = mlx5_get_sd (primary );
344
+ struct mlx5_sd * sd = mlx5_get_sd (secondary );
345
+ int err ;
346
+
347
+ err = mlx5_fs_cmd_set_l2table_entry_silent (secondary , 1 );
348
+ if (err )
349
+ return err ;
350
+
351
+ err = sd_secondary_create_alias_ft (secondary , primary , primary_sd -> tx_ft ,
352
+ & sd -> alias_obj_id , alias_key );
353
+ if (err )
354
+ goto err_unset_silent ;
355
+
356
+ err = mlx5_fs_cmd_set_tx_flow_table_root (secondary , sd -> alias_obj_id , false);
357
+ if (err )
358
+ goto err_destroy_alias_ft ;
359
+
360
+ return 0 ;
361
+
362
+ err_destroy_alias_ft :
363
+ sd_secondary_destroy_alias_ft (secondary );
364
+ err_unset_silent :
365
+ mlx5_fs_cmd_set_l2table_entry_silent (secondary , 0 );
366
+ return err ;
367
+ }
368
+
369
+ static void sd_cmd_unset_secondary (struct mlx5_core_dev * secondary )
370
+ {
371
+ mlx5_fs_cmd_set_tx_flow_table_root (secondary , 0 , true);
372
+ sd_secondary_destroy_alias_ft (secondary );
373
+ mlx5_fs_cmd_set_l2table_entry_silent (secondary , 0 );
374
+ }
375
+
230
376
int mlx5_sd_init (struct mlx5_core_dev * dev )
231
377
{
378
+ struct mlx5_core_dev * primary , * pos , * to ;
232
379
struct mlx5_sd * sd = mlx5_get_sd (dev );
233
- int err ;
380
+ u8 alias_key [ACCESS_KEY_LEN ];
381
+ int err , i ;
234
382
235
383
err = sd_init (dev );
236
384
if (err )
@@ -244,8 +392,33 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
244
392
if (err )
245
393
goto err_sd_cleanup ;
246
394
395
+ if (!mlx5_devcom_comp_is_ready (sd -> devcom ))
396
+ return 0 ;
397
+
398
+ primary = mlx5_sd_get_primary (dev );
399
+
400
+ for (i = 0 ; i < ACCESS_KEY_LEN ; i ++ )
401
+ alias_key [i ] = get_random_u8 ();
402
+
403
+ err = sd_cmd_set_primary (primary , alias_key );
404
+ if (err )
405
+ goto err_sd_unregister ;
406
+
407
+ mlx5_sd_for_each_secondary (i , primary , pos ) {
408
+ err = sd_cmd_set_secondary (pos , primary , alias_key );
409
+ if (err )
410
+ goto err_unset_secondaries ;
411
+ }
412
+
247
413
return 0 ;
248
414
415
+ err_unset_secondaries :
416
+ to = pos ;
417
+ mlx5_sd_for_each_secondary_to (i , primary , to , pos )
418
+ sd_cmd_unset_secondary (pos );
419
+ sd_cmd_unset_primary (primary );
420
+ err_sd_unregister :
421
+ sd_unregister (dev );
249
422
err_sd_cleanup :
250
423
sd_cleanup (dev );
251
424
return err ;
@@ -254,10 +427,20 @@ int mlx5_sd_init(struct mlx5_core_dev *dev)
254
427
void mlx5_sd_cleanup (struct mlx5_core_dev * dev )
255
428
{
256
429
struct mlx5_sd * sd = mlx5_get_sd (dev );
430
+ struct mlx5_core_dev * primary , * pos ;
431
+ int i ;
257
432
258
433
if (!sd )
259
434
return ;
260
435
436
+ if (!mlx5_devcom_comp_is_ready (sd -> devcom ))
437
+ goto out ;
438
+
439
+ primary = mlx5_sd_get_primary (dev );
440
+ mlx5_sd_for_each_secondary (i , primary , pos )
441
+ sd_cmd_unset_secondary (pos );
442
+ sd_cmd_unset_primary (primary );
443
+ out :
261
444
sd_unregister (dev );
262
445
sd_cleanup (dev );
263
446
}
0 commit comments