@@ -46,19 +46,13 @@ enum {
46
46
MLX5_ACTION_DEL = 2 ,
47
47
};
48
48
49
- /* E-Switch UC L2 table hash node */
50
- struct esw_uc_addr {
51
- struct l2addr_node node ;
52
- u32 table_index ;
53
- u32 vport ;
54
- };
55
-
56
49
/* Vport UC/MC hash node */
57
50
struct vport_addr {
58
51
struct l2addr_node node ;
59
52
u8 action ;
60
53
u32 vport ;
61
- struct mlx5_flow_handle * flow_rule ; /* SRIOV only */
54
+ struct mlx5_flow_handle * flow_rule ;
55
+ bool mpfs ; /* UC MAC was added to MPFs */
62
56
/* A flag indicating that mac was added due to mc promiscuous vport */
63
57
bool mc_promisc ;
64
58
};
@@ -154,81 +148,6 @@ static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u32 vport,
154
148
return modify_esw_vport_context_cmd (dev , vport , in , sizeof (in ));
155
149
}
156
150
157
- /* HW L2 Table (MPFS) management */
158
- static int set_l2_table_entry_cmd (struct mlx5_core_dev * dev , u32 index ,
159
- u8 * mac , u8 vlan_valid , u16 vlan )
160
- {
161
- u32 in [MLX5_ST_SZ_DW (set_l2_table_entry_in )] = {0 };
162
- u32 out [MLX5_ST_SZ_DW (set_l2_table_entry_out )] = {0 };
163
- u8 * in_mac_addr ;
164
-
165
- MLX5_SET (set_l2_table_entry_in , in , opcode ,
166
- MLX5_CMD_OP_SET_L2_TABLE_ENTRY );
167
- MLX5_SET (set_l2_table_entry_in , in , table_index , index );
168
- MLX5_SET (set_l2_table_entry_in , in , vlan_valid , vlan_valid );
169
- MLX5_SET (set_l2_table_entry_in , in , vlan , vlan );
170
-
171
- in_mac_addr = MLX5_ADDR_OF (set_l2_table_entry_in , in , mac_address );
172
- ether_addr_copy (& in_mac_addr [2 ], mac );
173
-
174
- return mlx5_cmd_exec (dev , in , sizeof (in ), out , sizeof (out ));
175
- }
176
-
177
- static int del_l2_table_entry_cmd (struct mlx5_core_dev * dev , u32 index )
178
- {
179
- u32 in [MLX5_ST_SZ_DW (delete_l2_table_entry_in )] = {0 };
180
- u32 out [MLX5_ST_SZ_DW (delete_l2_table_entry_out )] = {0 };
181
-
182
- MLX5_SET (delete_l2_table_entry_in , in , opcode ,
183
- MLX5_CMD_OP_DELETE_L2_TABLE_ENTRY );
184
- MLX5_SET (delete_l2_table_entry_in , in , table_index , index );
185
- return mlx5_cmd_exec (dev , in , sizeof (in ), out , sizeof (out ));
186
- }
187
-
188
- static int alloc_l2_table_index (struct mlx5_l2_table * l2_table , u32 * ix )
189
- {
190
- int err = 0 ;
191
-
192
- * ix = find_first_zero_bit (l2_table -> bitmap , l2_table -> size );
193
- if (* ix >= l2_table -> size )
194
- err = - ENOSPC ;
195
- else
196
- __set_bit (* ix , l2_table -> bitmap );
197
-
198
- return err ;
199
- }
200
-
201
- static void free_l2_table_index (struct mlx5_l2_table * l2_table , u32 ix )
202
- {
203
- __clear_bit (ix , l2_table -> bitmap );
204
- }
205
-
206
- static int set_l2_table_entry (struct mlx5_core_dev * dev , u8 * mac ,
207
- u8 vlan_valid , u16 vlan ,
208
- u32 * index )
209
- {
210
- struct mlx5_l2_table * l2_table = & dev -> priv .eswitch -> l2_table ;
211
- int err ;
212
-
213
- err = alloc_l2_table_index (l2_table , index );
214
- if (err )
215
- return err ;
216
-
217
- err = set_l2_table_entry_cmd (dev , * index , mac , vlan_valid , vlan );
218
- if (err )
219
- free_l2_table_index (l2_table , * index );
220
-
221
- return err ;
222
- }
223
-
224
- static void del_l2_table_entry (struct mlx5_core_dev * dev , u32 index )
225
- {
226
- struct mlx5_l2_table * l2_table = & dev -> priv .eswitch -> l2_table ;
227
-
228
- del_l2_table_entry_cmd (dev , index );
229
- free_l2_table_index (l2_table , index );
230
- }
231
-
232
151
/* E-Switch FDB */
233
152
static struct mlx5_flow_handle *
234
153
__esw_fdb_set_vport_rule (struct mlx5_eswitch * esw , u32 vport , bool rx_rule ,
@@ -455,65 +374,60 @@ typedef int (*vport_addr_action)(struct mlx5_eswitch *esw,
455
374
456
375
static int esw_add_uc_addr (struct mlx5_eswitch * esw , struct vport_addr * vaddr )
457
376
{
458
- struct hlist_head * hash = esw -> l2_table .l2_hash ;
459
- struct esw_uc_addr * esw_uc ;
460
377
u8 * mac = vaddr -> node .addr ;
461
378
u32 vport = vaddr -> vport ;
462
379
int err ;
463
380
464
- esw_uc = l2addr_hash_find (hash , mac , struct esw_uc_addr );
465
- if (esw_uc ) {
381
+ /* Skip mlx5_mpfs_add_mac for PFs,
382
+ * it is already done by the PF netdev in mlx5e_execute_l2_action
383
+ */
384
+ if (!vport )
385
+ goto fdb_add ;
386
+
387
+ err = mlx5_mpfs_add_mac (esw -> dev , mac );
388
+ if (err ) {
466
389
esw_warn (esw -> dev ,
467
- "Failed to set L2 mac(%pM) for vport(%d), mac is already in use by vport (%d)\n" ,
468
- mac , vport , esw_uc -> vport );
469
- return - EEXIST ;
390
+ "Failed to add L2 table mac(%pM) for vport(%d), err (%d)\n" ,
391
+ mac , vport , err );
392
+ return err ;
470
393
}
394
+ vaddr -> mpfs = true;
471
395
472
- esw_uc = l2addr_hash_add (hash , mac , struct esw_uc_addr , GFP_KERNEL );
473
- if (!esw_uc )
474
- return - ENOMEM ;
475
- esw_uc -> vport = vport ;
476
-
477
- err = set_l2_table_entry (esw -> dev , mac , 0 , 0 , & esw_uc -> table_index );
478
- if (err )
479
- goto abort ;
480
-
396
+ fdb_add :
481
397
/* SRIOV is enabled: Forward UC MAC to vport */
482
398
if (esw -> fdb_table .fdb && esw -> mode == SRIOV_LEGACY )
483
399
vaddr -> flow_rule = esw_fdb_set_vport_rule (esw , mac , vport );
484
400
485
- esw_debug (esw -> dev , "\tADDED UC MAC: vport[%d] %pM index:%d fr(%p)\n" ,
486
- vport , mac , esw_uc -> table_index , vaddr -> flow_rule );
487
- return err ;
488
- abort :
489
- l2addr_hash_del (esw_uc );
401
+ esw_debug (esw -> dev , "\tADDED UC MAC: vport[%d] %pM fr(%p)\n" ,
402
+ vport , mac , vaddr -> flow_rule );
403
+
490
404
return err ;
491
405
}
492
406
493
407
static int esw_del_uc_addr (struct mlx5_eswitch * esw , struct vport_addr * vaddr )
494
408
{
495
- struct hlist_head * hash = esw -> l2_table .l2_hash ;
496
- struct esw_uc_addr * esw_uc ;
497
409
u8 * mac = vaddr -> node .addr ;
498
410
u32 vport = vaddr -> vport ;
411
+ int err = 0 ;
499
412
500
- esw_uc = l2addr_hash_find (hash , mac , struct esw_uc_addr );
501
- if (!esw_uc || esw_uc -> vport != vport ) {
502
- esw_debug (esw -> dev ,
503
- "MAC(%pM) doesn't belong to vport (%d)\n" ,
504
- mac , vport );
505
- return - EINVAL ;
506
- }
507
- esw_debug (esw -> dev , "\tDELETE UC MAC: vport[%d] %pM index:%d fr(%p)\n" ,
508
- vport , mac , esw_uc -> table_index , vaddr -> flow_rule );
413
+ /* Skip mlx5_mpfs_del_mac for PFs,
414
+ * it is already done by the PF netdev in mlx5e_execute_l2_action
415
+ */
416
+ if (!vport || !vaddr -> mpfs )
417
+ goto fdb_del ;
509
418
510
- del_l2_table_entry (esw -> dev , esw_uc -> table_index );
419
+ err = mlx5_mpfs_del_mac (esw -> dev , mac );
420
+ if (err )
421
+ esw_warn (esw -> dev ,
422
+ "Failed to del L2 table mac(%pM) for vport(%d), err(%d)\n" ,
423
+ mac , vport , err );
424
+ vaddr -> mpfs = false;
511
425
426
+ fdb_del :
512
427
if (vaddr -> flow_rule )
513
428
mlx5_del_flow_rules (vaddr -> flow_rule );
514
429
vaddr -> flow_rule = NULL ;
515
430
516
- l2addr_hash_del (esw_uc );
517
431
return 0 ;
518
432
}
519
433
@@ -1635,7 +1549,6 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
1635
1549
1636
1550
esw_info (esw -> dev , "E-Switch enable SRIOV: nvfs(%d) mode (%d)\n" , nvfs , mode );
1637
1551
esw -> mode = mode ;
1638
- esw_disable_vport (esw , 0 );
1639
1552
1640
1553
if (mode == SRIOV_LEGACY )
1641
1554
err = esw_create_legacy_fdb_table (esw , nvfs + 1 );
@@ -1648,7 +1561,11 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
1648
1561
if (err )
1649
1562
esw_warn (esw -> dev , "Failed to create eswitch TSAR" );
1650
1563
1651
- enabled_events = (mode == SRIOV_LEGACY ) ? SRIOV_VPORT_EVENTS : UC_ADDR_CHANGE ;
1564
+ /* Don't enable vport events when in SRIOV_OFFLOADS mode, since:
1565
+ * 1. L2 table (MPFS) is programmed by PF/VF representors netdevs set_rx_mode
1566
+ * 2. FDB/Eswitch is programmed by user space tools
1567
+ */
1568
+ enabled_events = (mode == SRIOV_LEGACY ) ? SRIOV_VPORT_EVENTS : 0 ;
1652
1569
for (i = 0 ; i <= nvfs ; i ++ )
1653
1570
esw_enable_vport (esw , i , enabled_events );
1654
1571
@@ -1657,7 +1574,6 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
1657
1574
return 0 ;
1658
1575
1659
1576
abort :
1660
- esw_enable_vport (esw , 0 , UC_ADDR_CHANGE );
1661
1577
esw -> mode = SRIOV_NONE ;
1662
1578
return err ;
1663
1579
}
@@ -1691,30 +1607,10 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
1691
1607
esw_offloads_cleanup (esw , nvports );
1692
1608
1693
1609
esw -> mode = SRIOV_NONE ;
1694
- /* VPORT 0 (PF) must be enabled back with non-sriov configuration */
1695
- esw_enable_vport (esw , 0 , UC_ADDR_CHANGE );
1696
- }
1697
-
1698
- void mlx5_eswitch_attach (struct mlx5_eswitch * esw )
1699
- {
1700
- if (!ESW_ALLOWED (esw ))
1701
- return ;
1702
-
1703
- esw_enable_vport (esw , 0 , UC_ADDR_CHANGE );
1704
- /* VF Vports will be enabled when SRIOV is enabled */
1705
- }
1706
-
1707
- void mlx5_eswitch_detach (struct mlx5_eswitch * esw )
1708
- {
1709
- if (!ESW_ALLOWED (esw ))
1710
- return ;
1711
-
1712
- esw_disable_vport (esw , 0 );
1713
1610
}
1714
1611
1715
1612
int mlx5_eswitch_init (struct mlx5_core_dev * dev )
1716
1613
{
1717
- int l2_table_size = 1 << MLX5_CAP_GEN (dev , log_max_l2_table );
1718
1614
int total_vports = MLX5_TOTAL_VPORTS (dev );
1719
1615
struct mlx5_eswitch * esw ;
1720
1616
int vport_num ;
@@ -1724,8 +1620,8 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
1724
1620
return 0 ;
1725
1621
1726
1622
esw_info (dev ,
1727
- "Total vports %d, l2 table size(%d), per vport: max uc(%d) max mc(%d)\n" ,
1728
- total_vports , l2_table_size ,
1623
+ "Total vports %d, per vport: max uc(%d) max mc(%d)\n" ,
1624
+ total_vports ,
1729
1625
MLX5_MAX_UC_PER_VPORT (dev ),
1730
1626
MLX5_MAX_MC_PER_VPORT (dev ));
1731
1627
@@ -1735,14 +1631,6 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
1735
1631
1736
1632
esw -> dev = dev ;
1737
1633
1738
- esw -> l2_table .bitmap = kcalloc (BITS_TO_LONGS (l2_table_size ),
1739
- sizeof (uintptr_t ), GFP_KERNEL );
1740
- if (!esw -> l2_table .bitmap ) {
1741
- err = - ENOMEM ;
1742
- goto abort ;
1743
- }
1744
- esw -> l2_table .size = l2_table_size ;
1745
-
1746
1634
esw -> work_queue = create_singlethread_workqueue ("mlx5_esw_wq" );
1747
1635
if (!esw -> work_queue ) {
1748
1636
err = - ENOMEM ;
@@ -1793,7 +1681,6 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
1793
1681
abort :
1794
1682
if (esw -> work_queue )
1795
1683
destroy_workqueue (esw -> work_queue );
1796
- kfree (esw -> l2_table .bitmap );
1797
1684
kfree (esw -> vports );
1798
1685
kfree (esw -> offloads .vport_reps );
1799
1686
kfree (esw );
@@ -1809,7 +1696,6 @@ void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw)
1809
1696
1810
1697
esw -> dev -> priv .eswitch = NULL ;
1811
1698
destroy_workqueue (esw -> work_queue );
1812
- kfree (esw -> l2_table .bitmap );
1813
1699
kfree (esw -> offloads .vport_reps );
1814
1700
kfree (esw -> vports );
1815
1701
kfree (esw );
0 commit comments