aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c41
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c60
-rw-r--r--include/linux/mlx4/device.h7
3 files changed, 108 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index eb5ed8e39873..b7945a80ad15 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -301,6 +301,16 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
301 301
302 /* Enable promiscouos mode */ 302 /* Enable promiscouos mode */
303 switch (mdev->dev->caps.steering_mode) { 303 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
304 case MLX4_STEERING_MODE_B0: 314 case MLX4_STEERING_MODE_B0:
305 err = mlx4_unicast_promisc_add(mdev->dev, 315 err = mlx4_unicast_promisc_add(mdev->dev,
306 priv->base_qpn, 316 priv->base_qpn,
@@ -357,6 +367,15 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
357 367
358 /* Disable promiscouos mode */ 368 /* Disable promiscouos mode */
359 switch (mdev->dev->caps.steering_mode) { 369 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
360 case MLX4_STEERING_MODE_B0: 379 case MLX4_STEERING_MODE_B0:
361 err = mlx4_unicast_promisc_remove(mdev->dev, 380 err = mlx4_unicast_promisc_remove(mdev->dev,
362 priv->base_qpn, 381 priv->base_qpn,
@@ -399,6 +418,13 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
399 /* Add the default qp number as multicast promisc */ 418 /* Add the default qp number as multicast promisc */
400 if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { 419 if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) {
401 switch (mdev->dev->caps.steering_mode) { 420 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
402 case MLX4_STEERING_MODE_B0: 428 case MLX4_STEERING_MODE_B0:
403 err = mlx4_multicast_promisc_add(mdev->dev, 429 err = mlx4_multicast_promisc_add(mdev->dev,
404 priv->base_qpn, 430 priv->base_qpn,
@@ -416,6 +442,12 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
416 /* Disable Multicast promisc */ 442 /* Disable Multicast promisc */
417 if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { 443 if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) {
418 switch (mdev->dev->caps.steering_mode) { 444 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
419 case MLX4_STEERING_MODE_B0: 451 case MLX4_STEERING_MODE_B0:
420 err = mlx4_multicast_promisc_remove(mdev->dev, 452 err = mlx4_multicast_promisc_remove(mdev->dev,
421 priv->base_qpn, 453 priv->base_qpn,
@@ -839,6 +871,15 @@ int mlx4_en_start_port(struct net_device *dev)
839 871
840 /* Must redo promiscuous mode setup. */ 872 /* Must redo promiscuous mode setup. */
841 priv->flags &= ~(MLX4_EN_FLAG_PROMISC | MLX4_EN_FLAG_MC_PROMISC); 873 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 }
842 883
843 /* Schedule multicast task to populate multicast list */ 884 /* Schedule multicast task to populate multicast list */
844 queue_work(mdev->workqueue, &priv->mcast_task); 885 queue_work(mdev->workqueue, &priv->mcast_task);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 768a2a4530e8..bc62f536ffae 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -1295,6 +1295,66 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
1295} 1295}
1296EXPORT_SYMBOL_GPL(mlx4_multicast_detach); 1296EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
1297 1297
1298int 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}
1327EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_add);
1328
1329int 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}
1356EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_remove);
1357
1298int mlx4_unicast_attach(struct mlx4_dev *dev, 1358int mlx4_unicast_attach(struct mlx4_dev *dev,
1299 struct mlx4_qp *qp, u8 gid[16], 1359 struct mlx4_qp *qp, u8 gid[16],
1300 int block_mcast_loopback, enum mlx4_protocol prot) 1360 int block_mcast_loopback, enum mlx4_protocol prot)
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index e45fc20bd01f..6f0d133cc7ad 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -542,6 +542,8 @@ struct mlx4_dev {
542 u8 rev_id; 542 u8 rev_id;
543 char board_id[MLX4_BOARD_ID_LEN]; 543 char board_id[MLX4_BOARD_ID_LEN];
544 int num_vfs; 544 int num_vfs;
545 u64 regid_promisc_array[MLX4_MAX_PORTS + 1];
546 u64 regid_allmulti_array[MLX4_MAX_PORTS + 1];
545}; 547};
546 548
547struct mlx4_init_port_param { 549struct mlx4_init_port_param {
@@ -681,6 +683,7 @@ enum mlx4_net_trans_rule_id {
681enum mlx4_net_trans_promisc_mode { 683enum mlx4_net_trans_promisc_mode {
682 MLX4_FS_PROMISC_NONE = 0, 684 MLX4_FS_PROMISC_NONE = 0,
683 MLX4_FS_PROMISC_UPLINK, 685 MLX4_FS_PROMISC_UPLINK,
686 /* For future use. Not implemented yet */
684 MLX4_FS_PROMISC_FUNCTION_PORT, 687 MLX4_FS_PROMISC_FUNCTION_PORT,
685 MLX4_FS_PROMISC_ALL_MULTI, 688 MLX4_FS_PROMISC_ALL_MULTI,
686}; 689};
@@ -744,6 +747,10 @@ struct mlx4_net_trans_rule {
744 u32 qpn; 747 u32 qpn;
745}; 748};
746 749
750int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, u32 qpn,
751 enum mlx4_net_trans_promisc_mode mode);
752int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port,
753 enum mlx4_net_trans_promisc_mode mode);
747int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); 754int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port);
748int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port); 755int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port);
749int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); 756int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port);