Skip to content

Commit 9902b63

Browse files
Saeed MahameedPaolo Abeni
authored andcommitted
net/mlx5: MPFS, add support for dynamic enable/disable
MPFS (Multi PF Switch) is enabled by default in Multi-Host environments, the driver keeps a list of desired unicast mac addresses of all vports (vfs/Sfs) and applied to HW via L2_table FW command. Add API to dynamically apply the list of MACs to HW when needed for next patches, to utilize this new API in devlink eswitch active/in-active uAPI. Signed-off-by: Saeed Mahameed <[email protected]> Signed-off-by: Adithya Jayachandran <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 0e53582 commit 9902b63

File tree

2 files changed

+108
-17
lines changed

2 files changed

+108
-17
lines changed

drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c

Lines changed: 99 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,14 @@ static int del_l2table_entry_cmd(struct mlx5_core_dev *dev, u32 index)
6565
/* UC L2 table hash node */
6666
struct l2table_node {
6767
struct l2addr_node node;
68-
u32 index; /* index in HW l2 table */
68+
int index; /* index in HW l2 table */
6969
int ref_count;
7070
};
7171

7272
struct mlx5_mpfs {
7373
struct hlist_head hash[MLX5_L2_ADDR_HASH_SIZE];
7474
struct mutex lock; /* Synchronize l2 table access */
75+
bool enabled;
7576
u32 size;
7677
unsigned long *bitmap;
7778
};
@@ -114,6 +115,8 @@ int mlx5_mpfs_init(struct mlx5_core_dev *dev)
114115
return -ENOMEM;
115116
}
116117

118+
mpfs->enabled = true;
119+
117120
dev->priv.mpfs = mpfs;
118121
return 0;
119122
}
@@ -135,7 +138,7 @@ int mlx5_mpfs_add_mac(struct mlx5_core_dev *dev, u8 *mac)
135138
struct mlx5_mpfs *mpfs = dev->priv.mpfs;
136139
struct l2table_node *l2addr;
137140
int err = 0;
138-
u32 index;
141+
int index;
139142

140143
if (!mpfs)
141144
return 0;
@@ -148,30 +151,34 @@ int mlx5_mpfs_add_mac(struct mlx5_core_dev *dev, u8 *mac)
148151
goto out;
149152
}
150153

151-
err = alloc_l2table_index(mpfs, &index);
152-
if (err)
153-
goto out;
154-
155154
l2addr = l2addr_hash_add(mpfs->hash, mac, struct l2table_node, GFP_KERNEL);
156155
if (!l2addr) {
157156
err = -ENOMEM;
158-
goto hash_add_err;
157+
goto out;
159158
}
160159

161-
err = set_l2table_entry_cmd(dev, index, mac);
162-
if (err)
163-
goto set_table_entry_err;
160+
index = -1;
161+
162+
if (mpfs->enabled) {
163+
err = alloc_l2table_index(mpfs, &index);
164+
if (err)
165+
goto hash_del;
166+
err = set_l2table_entry_cmd(dev, index, mac);
167+
if (err)
168+
goto free_l2table_index;
169+
mlx5_core_dbg(dev, "MPFS entry %pM, set @index (%d)\n",
170+
l2addr->node.addr, l2addr->index);
171+
}
164172

165173
l2addr->index = index;
166174
l2addr->ref_count = 1;
167175

168176
mlx5_core_dbg(dev, "MPFS mac added %pM, index (%d)\n", mac, index);
169177
goto out;
170-
171-
set_table_entry_err:
172-
l2addr_hash_del(l2addr);
173-
hash_add_err:
178+
free_l2table_index:
174179
free_l2table_index(mpfs, index);
180+
hash_del:
181+
l2addr_hash_del(l2addr);
175182
out:
176183
mutex_unlock(&mpfs->lock);
177184
return err;
@@ -183,7 +190,7 @@ int mlx5_mpfs_del_mac(struct mlx5_core_dev *dev, u8 *mac)
183190
struct mlx5_mpfs *mpfs = dev->priv.mpfs;
184191
struct l2table_node *l2addr;
185192
int err = 0;
186-
u32 index;
193+
int index;
187194

188195
if (!mpfs)
189196
return 0;
@@ -200,12 +207,87 @@ int mlx5_mpfs_del_mac(struct mlx5_core_dev *dev, u8 *mac)
200207
goto unlock;
201208

202209
index = l2addr->index;
203-
del_l2table_entry_cmd(dev, index);
210+
if (index >= 0) {
211+
del_l2table_entry_cmd(dev, index);
212+
free_l2table_index(mpfs, index);
213+
mlx5_core_dbg(dev, "MPFS entry %pM, deleted @index (%d)\n",
214+
mac, index);
215+
}
204216
l2addr_hash_del(l2addr);
205-
free_l2table_index(mpfs, index);
206217
mlx5_core_dbg(dev, "MPFS mac deleted %pM, index (%d)\n", mac, index);
207218
unlock:
208219
mutex_unlock(&mpfs->lock);
209220
return err;
210221
}
211222
EXPORT_SYMBOL(mlx5_mpfs_del_mac);
223+
224+
int mlx5_mpfs_enable(struct mlx5_core_dev *dev)
225+
{
226+
struct mlx5_mpfs *mpfs = dev->priv.mpfs;
227+
struct l2table_node *l2addr;
228+
struct hlist_node *n;
229+
int err = 0, i;
230+
231+
if (!mpfs)
232+
return -ENODEV;
233+
234+
mutex_lock(&mpfs->lock);
235+
if (mpfs->enabled)
236+
goto out;
237+
mpfs->enabled = true;
238+
mlx5_core_dbg(dev, "MPFS enabling mpfs\n");
239+
240+
mlx5_mpfs_foreach(l2addr, n, mpfs, i) {
241+
u32 index;
242+
243+
err = alloc_l2table_index(mpfs, &index);
244+
if (err) {
245+
mlx5_core_err(dev, "Failed to allocated MPFS index for %pM, err(%d)\n",
246+
l2addr->node.addr, err);
247+
goto out;
248+
}
249+
250+
err = set_l2table_entry_cmd(dev, index, l2addr->node.addr);
251+
if (err) {
252+
mlx5_core_err(dev, "Failed to set MPFS l2table entry for %pM index=%d, err(%d)\n",
253+
l2addr->node.addr, index, err);
254+
free_l2table_index(mpfs, index);
255+
goto out;
256+
}
257+
258+
l2addr->index = index;
259+
mlx5_core_dbg(dev, "MPFS entry %pM, set @index (%d)\n",
260+
l2addr->node.addr, l2addr->index);
261+
}
262+
out:
263+
mutex_unlock(&mpfs->lock);
264+
return err;
265+
}
266+
267+
void mlx5_mpfs_disable(struct mlx5_core_dev *dev)
268+
{
269+
struct mlx5_mpfs *mpfs = dev->priv.mpfs;
270+
struct l2table_node *l2addr;
271+
struct hlist_node *n;
272+
int i;
273+
274+
if (!mpfs)
275+
return;
276+
277+
mutex_lock(&mpfs->lock);
278+
if (!mpfs->enabled)
279+
goto unlock;
280+
mlx5_mpfs_foreach(l2addr, n, mpfs, i) {
281+
if (l2addr->index < 0)
282+
continue;
283+
del_l2table_entry_cmd(dev, l2addr->index);
284+
free_l2table_index(mpfs, l2addr->index);
285+
mlx5_core_dbg(dev, "MPFS entry %pM, deleted @index (%d)\n",
286+
l2addr->node.addr, l2addr->index);
287+
l2addr->index = -1;
288+
}
289+
mpfs->enabled = false;
290+
mlx5_core_dbg(dev, "MPFS disabled\n");
291+
unlock:
292+
mutex_unlock(&mpfs->lock);
293+
}

drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ struct l2addr_node {
4545
u8 addr[ETH_ALEN];
4646
};
4747

48+
#define mlx5_mpfs_foreach(hs, tmp, mpfs, i) \
49+
for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \
50+
hlist_for_each_entry_safe(hs, tmp, &(mpfs)->hash[i], node.hlist)
51+
4852
#define for_each_l2hash_node(hn, tmp, hash, i) \
4953
for (i = 0; i < MLX5_L2_ADDR_HASH_SIZE; i++) \
5054
hlist_for_each_entry_safe(hn, tmp, &(hash)[i], hlist)
@@ -82,11 +86,16 @@ struct l2addr_node {
8286
})
8387

8488
#ifdef CONFIG_MLX5_MPFS
89+
struct mlx5_core_dev;
8590
int mlx5_mpfs_init(struct mlx5_core_dev *dev);
8691
void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev);
92+
int mlx5_mpfs_enable(struct mlx5_core_dev *dev);
93+
void mlx5_mpfs_disable(struct mlx5_core_dev *dev);
8794
#else /* #ifndef CONFIG_MLX5_MPFS */
8895
static inline int mlx5_mpfs_init(struct mlx5_core_dev *dev) { return 0; }
8996
static inline void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev) {}
97+
static inline int mlx5_mpfs_enable(struct mlx5_core_dev *dev) { return 0; }
98+
static inline void mlx5_mpfs_disable(struct mlx5_core_dev *dev) {}
9099
#endif
91100

92101
#endif

0 commit comments

Comments
 (0)