diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 41 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mcg.c | 60 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 7 |
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 | } |
1296 | EXPORT_SYMBOL_GPL(mlx4_multicast_detach); | 1296 | EXPORT_SYMBOL_GPL(mlx4_multicast_detach); |
1297 | 1297 | ||
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 | |||
1298 | int mlx4_unicast_attach(struct mlx4_dev *dev, | 1358 | int 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 | ||
547 | struct mlx4_init_port_param { | 549 | struct mlx4_init_port_param { |
@@ -681,6 +683,7 @@ enum mlx4_net_trans_rule_id { | |||
681 | enum mlx4_net_trans_promisc_mode { | 683 | enum 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 | ||
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); | ||
747 | int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); | 754 | int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); |
748 | int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port); | 755 | int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port); |
749 | int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); | 756 | int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port); |