Skip to content

Commit 592e49d

Browse files
Hadar Hen Ziondavem330
authored andcommitted
net/mlx4: Implement promiscuous mode with device managed flow-steering
The device managed flow steering API has three promiscuous modes: 1. Uplink - captures all the packets that arrive to the port. 2. Allmulti - captures all multicast packets arriving to the port. 3. Function port - for future use, this mode is not implemented yet. Use these modes with the flow_attach and flow_detach firmware commands according to the promiscuous state of the netdevice. Signed-off-by: Hadar Hen Zion <hadarh@mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 1b9c6b0 commit 592e49d

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

drivers/net/ethernet/mellanox/mlx4/en_netdev.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,16 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
301301

302302
/* Enable promiscouos mode */
303303
switch (mdev->dev->caps.steering_mode) {
304+
case MLX4_STEERING_MODE_DEVICE_MANAGED:
305+
err = mlx4_flow_steer_promisc_add(mdev->dev,
306+
priv->port,
307+
priv->base_qpn,
308+
MLX4_FS_PROMISC_UPLINK);
309+
if (err)
310+
en_err(priv, "Failed enabling promiscuous mode\n");
311+
priv->flags |= MLX4_EN_FLAG_MC_PROMISC;
312+
break;
313+
304314
case MLX4_STEERING_MODE_B0:
305315
err = mlx4_unicast_promisc_add(mdev->dev,
306316
priv->base_qpn,
@@ -357,6 +367,15 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
357367

358368
/* Disable promiscouos mode */
359369
switch (mdev->dev->caps.steering_mode) {
370+
case MLX4_STEERING_MODE_DEVICE_MANAGED:
371+
err = mlx4_flow_steer_promisc_remove(mdev->dev,
372+
priv->port,
373+
MLX4_FS_PROMISC_UPLINK);
374+
if (err)
375+
en_err(priv, "Failed disabling promiscuous mode\n");
376+
priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC;
377+
break;
378+
360379
case MLX4_STEERING_MODE_B0:
361380
err = mlx4_unicast_promisc_remove(mdev->dev,
362381
priv->base_qpn,
@@ -399,6 +418,13 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
399418
/* Add the default qp number as multicast promisc */
400419
if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) {
401420
switch (mdev->dev->caps.steering_mode) {
421+
case MLX4_STEERING_MODE_DEVICE_MANAGED:
422+
err = mlx4_flow_steer_promisc_add(mdev->dev,
423+
priv->port,
424+
priv->base_qpn,
425+
MLX4_FS_PROMISC_ALL_MULTI);
426+
break;
427+
402428
case MLX4_STEERING_MODE_B0:
403429
err = mlx4_multicast_promisc_add(mdev->dev,
404430
priv->base_qpn,
@@ -416,6 +442,12 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
416442
/* Disable Multicast promisc */
417443
if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) {
418444
switch (mdev->dev->caps.steering_mode) {
445+
case MLX4_STEERING_MODE_DEVICE_MANAGED:
446+
err = mlx4_flow_steer_promisc_remove(mdev->dev,
447+
priv->port,
448+
MLX4_FS_PROMISC_ALL_MULTI);
449+
break;
450+
419451
case MLX4_STEERING_MODE_B0:
420452
err = mlx4_multicast_promisc_remove(mdev->dev,
421453
priv->base_qpn,
@@ -839,6 +871,15 @@ int mlx4_en_start_port(struct net_device *dev)
839871

840872
/* Must redo promiscuous mode setup. */
841873
priv->flags &= ~(MLX4_EN_FLAG_PROMISC | MLX4_EN_FLAG_MC_PROMISC);
874+
if (mdev->dev->caps.steering_mode ==
875+
MLX4_STEERING_MODE_DEVICE_MANAGED) {
876+
mlx4_flow_steer_promisc_remove(mdev->dev,
877+
priv->port,
878+
MLX4_FS_PROMISC_UPLINK);
879+
mlx4_flow_steer_promisc_remove(mdev->dev,
880+
priv->port,
881+
MLX4_FS_PROMISC_ALL_MULTI);
882+
}
842883

843884
/* Schedule multicast task to populate multicast list */
844885
queue_work(mdev->workqueue, &priv->mcast_task);

drivers/net/ethernet/mellanox/mlx4/mcg.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,66 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
12951295
}
12961296
EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
12971297

1298+
int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port,
1299+
u32 qpn, enum mlx4_net_trans_promisc_mode mode)
1300+
{
1301+
struct mlx4_net_trans_rule rule;
1302+
u64 *regid_p;
1303+
1304+
switch (mode) {
1305+
case MLX4_FS_PROMISC_UPLINK:
1306+
case MLX4_FS_PROMISC_FUNCTION_PORT:
1307+
regid_p = &dev->regid_promisc_array[port];
1308+
break;
1309+
case MLX4_FS_PROMISC_ALL_MULTI:
1310+
regid_p = &dev->regid_allmulti_array[port];
1311+
break;
1312+
default:
1313+
return -1;
1314+
}
1315+
1316+
if (*regid_p != 0)
1317+
return -1;
1318+
1319+
rule.promisc_mode = mode;
1320+
rule.port = port;
1321+
rule.qpn = qpn;
1322+
INIT_LIST_HEAD(&rule.list);
1323+
mlx4_err(dev, "going promisc on %x\n", port);
1324+
1325+
return mlx4_flow_attach(dev, &rule, regid_p);
1326+
}
1327+
EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_add);
1328+
1329+
int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port,
1330+
enum mlx4_net_trans_promisc_mode mode)
1331+
{
1332+
int ret;
1333+
u64 *regid_p;
1334+
1335+
switch (mode) {
1336+
case MLX4_FS_PROMISC_UPLINK:
1337+
case MLX4_FS_PROMISC_FUNCTION_PORT:
1338+
regid_p = &dev->regid_promisc_array[port];
1339+
break;
1340+
case MLX4_FS_PROMISC_ALL_MULTI:
1341+
regid_p = &dev->regid_allmulti_array[port];
1342+
break;
1343+
default:
1344+
return -1;
1345+
}
1346+
1347+
if (*regid_p == 0)
1348+
return -1;
1349+
1350+
ret = mlx4_flow_detach(dev, *regid_p);
1351+
if (ret == 0)
1352+
*regid_p = 0;
1353+
1354+
return ret;
1355+
}
1356+
EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_remove);
1357+
12981358
int mlx4_unicast_attach(struct mlx4_dev *dev,
12991359
struct mlx4_qp *qp, u8 gid[16],
13001360
int block_mcast_loopback, enum mlx4_protocol prot)

include/linux/mlx4/device.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,8 @@ struct mlx4_dev {
542542
u8 rev_id;
543543
char board_id[MLX4_BOARD_ID_LEN];
544544
int num_vfs;
545+
u64 regid_promisc_array[MLX4_MAX_PORTS + 1];
546+
u64 regid_allmulti_array[MLX4_MAX_PORTS + 1];
545547
};
546548

547549
struct mlx4_init_port_param {
@@ -681,6 +683,7 @@ enum mlx4_net_trans_rule_id {
681683
enum mlx4_net_trans_promisc_mode {
682684
MLX4_FS_PROMISC_NONE = 0,
683685
MLX4_FS_PROMISC_UPLINK,
686+
/* For future use. Not implemented yet */
684687
MLX4_FS_PROMISC_FUNCTION_PORT,
685688
MLX4_FS_PROMISC_ALL_MULTI,
686689
};
@@ -744,6 +747,10 @@ struct mlx4_net_trans_rule {
744747
u32 qpn;
745748
};
746749

750+
int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, u32 qpn,
751+
enum mlx4_net_trans_promisc_mode mode);
752+
int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port,
753+
enum mlx4_net_trans_promisc_mode mode);
747754
int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port);
748755
int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port);
749756
int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port);

0 commit comments

Comments
 (0)