diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 108 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mcg.c | 70 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/port.c | 9 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 24 |
6 files changed, 148 insertions, 81 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index bedcbb30d38..44ff7cdb15e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -265,7 +265,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
265 | struct mlx4_en_mc_list *mclist, *tmp; | 265 | struct mlx4_en_mc_list *mclist, *tmp; |
266 | u64 mcast_addr = 0; | 266 | u64 mcast_addr = 0; |
267 | u8 mc_list[16] = {0}; | 267 | u8 mc_list[16] = {0}; |
268 | int err; | 268 | int err = 0; |
269 | 269 | ||
270 | mutex_lock(&mdev->state_lock); | 270 | mutex_lock(&mdev->state_lock); |
271 | if (!mdev->device_up) { | 271 | if (!mdev->device_up) { |
@@ -300,16 +300,36 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
300 | priv->flags |= MLX4_EN_FLAG_PROMISC; | 300 | priv->flags |= MLX4_EN_FLAG_PROMISC; |
301 | 301 | ||
302 | /* Enable promiscouos mode */ | 302 | /* Enable promiscouos mode */ |
303 | if (!(mdev->dev->caps.flags & | 303 | switch (mdev->dev->caps.steering_mode) { |
304 | MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) | 304 | case MLX4_STEERING_MODE_B0: |
305 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, | 305 | err = mlx4_unicast_promisc_add(mdev->dev, |
306 | priv->base_qpn, 1); | 306 | priv->base_qpn, |
307 | else | ||
308 | err = mlx4_unicast_promisc_add(mdev->dev, priv->base_qpn, | ||
309 | priv->port); | 307 | priv->port); |
310 | if (err) | 308 | if (err) |
311 | en_err(priv, "Failed enabling " | 309 | en_err(priv, "Failed enabling unicast promiscuous mode\n"); |
312 | "promiscuous mode\n"); | 310 | |
311 | /* Add the default qp number as multicast | ||
312 | * promisc | ||
313 | */ | ||
314 | if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { | ||
315 | err = mlx4_multicast_promisc_add(mdev->dev, | ||
316 | priv->base_qpn, | ||
317 | priv->port); | ||
318 | if (err) | ||
319 | en_err(priv, "Failed enabling multicast promiscuous mode\n"); | ||
320 | priv->flags |= MLX4_EN_FLAG_MC_PROMISC; | ||
321 | } | ||
322 | break; | ||
323 | |||
324 | case MLX4_STEERING_MODE_A0: | ||
325 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, | ||
326 | priv->port, | ||
327 | priv->base_qpn, | ||
328 | 1); | ||
329 | if (err) | ||
330 | en_err(priv, "Failed enabling promiscuous mode\n"); | ||
331 | break; | ||
332 | } | ||
313 | 333 | ||
314 | /* Disable port multicast filter (unconditionally) */ | 334 | /* Disable port multicast filter (unconditionally) */ |
315 | err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, | 335 | err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, |
@@ -318,15 +338,6 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
318 | en_err(priv, "Failed disabling " | 338 | en_err(priv, "Failed disabling " |
319 | "multicast filter\n"); | 339 | "multicast filter\n"); |
320 | 340 | ||
321 | /* Add the default qp number as multicast promisc */ | ||
322 | if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { | ||
323 | err = mlx4_multicast_promisc_add(mdev->dev, priv->base_qpn, | ||
324 | priv->port); | ||
325 | if (err) | ||
326 | en_err(priv, "Failed entering multicast promisc mode\n"); | ||
327 | priv->flags |= MLX4_EN_FLAG_MC_PROMISC; | ||
328 | } | ||
329 | |||
330 | /* Disable port VLAN filter */ | 341 | /* Disable port VLAN filter */ |
331 | err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); | 342 | err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); |
332 | if (err) | 343 | if (err) |
@@ -345,22 +356,31 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
345 | priv->flags &= ~MLX4_EN_FLAG_PROMISC; | 356 | priv->flags &= ~MLX4_EN_FLAG_PROMISC; |
346 | 357 | ||
347 | /* Disable promiscouos mode */ | 358 | /* Disable promiscouos mode */ |
348 | if (!(mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) | 359 | switch (mdev->dev->caps.steering_mode) { |
349 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, | 360 | case MLX4_STEERING_MODE_B0: |
350 | priv->base_qpn, 0); | 361 | err = mlx4_unicast_promisc_remove(mdev->dev, |
351 | else | 362 | priv->base_qpn, |
352 | err = mlx4_unicast_promisc_remove(mdev->dev, priv->base_qpn, | ||
353 | priv->port); | 363 | priv->port); |
354 | if (err) | 364 | if (err) |
355 | en_err(priv, "Failed disabling promiscuous mode\n"); | 365 | en_err(priv, "Failed disabling unicast promiscuous mode\n"); |
366 | /* Disable Multicast promisc */ | ||
367 | if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { | ||
368 | err = mlx4_multicast_promisc_remove(mdev->dev, | ||
369 | priv->base_qpn, | ||
370 | priv->port); | ||
371 | if (err) | ||
372 | en_err(priv, "Failed disabling multicast promiscuous mode\n"); | ||
373 | priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; | ||
374 | } | ||
375 | break; | ||
356 | 376 | ||
357 | /* Disable Multicast promisc */ | 377 | case MLX4_STEERING_MODE_A0: |
358 | if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { | 378 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, |
359 | err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn, | 379 | priv->port, |
360 | priv->port); | 380 | priv->base_qpn, 0); |
361 | if (err) | 381 | if (err) |
362 | en_err(priv, "Failed disabling multicast promiscuous mode\n"); | 382 | en_err(priv, "Failed disabling promiscuous mode\n"); |
363 | priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; | 383 | break; |
364 | } | 384 | } |
365 | 385 | ||
366 | /* Enable port VLAN filter */ | 386 | /* Enable port VLAN filter */ |
@@ -378,8 +398,16 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
378 | 398 | ||
379 | /* Add the default qp number as multicast promisc */ | 399 | /* Add the default qp number as multicast promisc */ |
380 | if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { | 400 | if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { |
381 | err = mlx4_multicast_promisc_add(mdev->dev, priv->base_qpn, | 401 | switch (mdev->dev->caps.steering_mode) { |
382 | priv->port); | 402 | case MLX4_STEERING_MODE_B0: |
403 | err = mlx4_multicast_promisc_add(mdev->dev, | ||
404 | priv->base_qpn, | ||
405 | priv->port); | ||
406 | break; | ||
407 | |||
408 | case MLX4_STEERING_MODE_A0: | ||
409 | break; | ||
410 | } | ||
383 | if (err) | 411 | if (err) |
384 | en_err(priv, "Failed entering multicast promisc mode\n"); | 412 | en_err(priv, "Failed entering multicast promisc mode\n"); |
385 | priv->flags |= MLX4_EN_FLAG_MC_PROMISC; | 413 | priv->flags |= MLX4_EN_FLAG_MC_PROMISC; |
@@ -387,8 +415,16 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
387 | } else { | 415 | } else { |
388 | /* Disable Multicast promisc */ | 416 | /* Disable Multicast promisc */ |
389 | if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { | 417 | if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { |
390 | err = mlx4_multicast_promisc_remove(mdev->dev, priv->base_qpn, | 418 | switch (mdev->dev->caps.steering_mode) { |
391 | priv->port); | 419 | case MLX4_STEERING_MODE_B0: |
420 | err = mlx4_multicast_promisc_remove(mdev->dev, | ||
421 | priv->base_qpn, | ||
422 | priv->port); | ||
423 | break; | ||
424 | |||
425 | case MLX4_STEERING_MODE_A0: | ||
426 | break; | ||
427 | } | ||
392 | if (err) | 428 | if (err) |
393 | en_err(priv, "Failed disabling multicast promiscuous mode\n"); | 429 | en_err(priv, "Failed disabling multicast promiscuous mode\n"); |
394 | priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; | 430 | priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 9c83bb8151e..40e048bac02 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -1124,7 +1124,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
1124 | MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); | 1124 | MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); |
1125 | MLX4_PUT(inbox, param->log_mc_entry_sz, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); | 1125 | MLX4_PUT(inbox, param->log_mc_entry_sz, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); |
1126 | MLX4_PUT(inbox, param->log_mc_hash_sz, INIT_HCA_LOG_MC_HASH_SZ_OFFSET); | 1126 | MLX4_PUT(inbox, param->log_mc_hash_sz, INIT_HCA_LOG_MC_HASH_SZ_OFFSET); |
1127 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) | 1127 | if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0) |
1128 | MLX4_PUT(inbox, (u8) (1 << 3), INIT_HCA_UC_STEERING_OFFSET); | 1128 | MLX4_PUT(inbox, (u8) (1 << 3), INIT_HCA_UC_STEERING_OFFSET); |
1129 | MLX4_PUT(inbox, param->log_mc_table_sz, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); | 1129 | MLX4_PUT(inbox, param->log_mc_table_sz, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); |
1130 | 1130 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 14d9c762b60..f8125a82c0c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -244,7 +244,6 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
244 | dev->caps.reserved_srqs = dev_cap->reserved_srqs; | 244 | dev->caps.reserved_srqs = dev_cap->reserved_srqs; |
245 | dev->caps.max_sq_desc_sz = dev_cap->max_sq_desc_sz; | 245 | dev->caps.max_sq_desc_sz = dev_cap->max_sq_desc_sz; |
246 | dev->caps.max_rq_desc_sz = dev_cap->max_rq_desc_sz; | 246 | dev->caps.max_rq_desc_sz = dev_cap->max_rq_desc_sz; |
247 | dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); | ||
248 | /* | 247 | /* |
249 | * Subtract 1 from the limit because we need to allocate a | 248 | * Subtract 1 from the limit because we need to allocate a |
250 | * spare CQE so the HCA HW can tell the difference between an | 249 | * spare CQE so the HCA HW can tell the difference between an |
@@ -275,6 +274,21 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
275 | dev->caps.max_gso_sz = dev_cap->max_gso_sz; | 274 | dev->caps.max_gso_sz = dev_cap->max_gso_sz; |
276 | dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz; | 275 | dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz; |
277 | 276 | ||
277 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && | ||
278 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) { | ||
279 | dev->caps.steering_mode = MLX4_STEERING_MODE_B0; | ||
280 | } else { | ||
281 | dev->caps.steering_mode = MLX4_STEERING_MODE_A0; | ||
282 | |||
283 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER || | ||
284 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) | ||
285 | mlx4_warn(dev, "Must have UC_STEER and MC_STEER flags " | ||
286 | "set to use B0 steering. Falling back to A0 steering mode.\n"); | ||
287 | } | ||
288 | mlx4_dbg(dev, "Steering mode is: %s\n", | ||
289 | mlx4_steering_mode_str(dev->caps.steering_mode)); | ||
290 | dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); | ||
291 | |||
278 | /* Sense port always allowed on supported devices for ConnectX1 and 2 */ | 292 | /* Sense port always allowed on supported devices for ConnectX1 and 2 */ |
279 | if (dev->pdev->device != 0x1003) | 293 | if (dev->pdev->device != 0x1003) |
280 | dev->caps.flags |= MLX4_DEV_CAP_FLAG_SENSE_SUPPORT; | 294 | dev->caps.flags |= MLX4_DEV_CAP_FLAG_SENSE_SUPPORT; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index f4a8f98e402..319c9d45d59 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
@@ -868,36 +868,50 @@ static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp, | |||
868 | int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], | 868 | int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], |
869 | int block_mcast_loopback, enum mlx4_protocol prot) | 869 | int block_mcast_loopback, enum mlx4_protocol prot) |
870 | { | 870 | { |
871 | if (prot == MLX4_PROT_ETH && | ||
872 | !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) | ||
873 | return 0; | ||
874 | 871 | ||
875 | if (prot == MLX4_PROT_ETH) | 872 | switch (dev->caps.steering_mode) { |
876 | gid[7] |= (MLX4_MC_STEER << 1); | 873 | case MLX4_STEERING_MODE_A0: |
874 | if (prot == MLX4_PROT_ETH) | ||
875 | return 0; | ||
877 | 876 | ||
878 | if (mlx4_is_mfunc(dev)) | 877 | case MLX4_STEERING_MODE_B0: |
879 | return mlx4_QP_ATTACH(dev, qp, gid, 1, | 878 | if (prot == MLX4_PROT_ETH) |
880 | block_mcast_loopback, prot); | 879 | gid[7] |= (MLX4_MC_STEER << 1); |
881 | 880 | ||
882 | return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback, | 881 | if (mlx4_is_mfunc(dev)) |
883 | prot, MLX4_MC_STEER); | 882 | return mlx4_QP_ATTACH(dev, qp, gid, 1, |
883 | block_mcast_loopback, prot); | ||
884 | return mlx4_qp_attach_common(dev, qp, gid, | ||
885 | block_mcast_loopback, prot, | ||
886 | MLX4_MC_STEER); | ||
887 | |||
888 | default: | ||
889 | return -EINVAL; | ||
890 | } | ||
884 | } | 891 | } |
885 | EXPORT_SYMBOL_GPL(mlx4_multicast_attach); | 892 | EXPORT_SYMBOL_GPL(mlx4_multicast_attach); |
886 | 893 | ||
887 | int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], | 894 | int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], |
888 | enum mlx4_protocol prot) | 895 | enum mlx4_protocol prot) |
889 | { | 896 | { |
890 | if (prot == MLX4_PROT_ETH && | 897 | switch (dev->caps.steering_mode) { |
891 | !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) | 898 | case MLX4_STEERING_MODE_A0: |
892 | return 0; | 899 | if (prot == MLX4_PROT_ETH) |
900 | return 0; | ||
893 | 901 | ||
894 | if (prot == MLX4_PROT_ETH) | 902 | case MLX4_STEERING_MODE_B0: |
895 | gid[7] |= (MLX4_MC_STEER << 1); | 903 | if (prot == MLX4_PROT_ETH) |
904 | gid[7] |= (MLX4_MC_STEER << 1); | ||
896 | 905 | ||
897 | if (mlx4_is_mfunc(dev)) | 906 | if (mlx4_is_mfunc(dev)) |
898 | return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); | 907 | return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); |
908 | |||
909 | return mlx4_qp_detach_common(dev, qp, gid, prot, | ||
910 | MLX4_MC_STEER); | ||
899 | 911 | ||
900 | return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_MC_STEER); | 912 | default: |
913 | return -EINVAL; | ||
914 | } | ||
901 | } | 915 | } |
902 | EXPORT_SYMBOL_GPL(mlx4_multicast_detach); | 916 | EXPORT_SYMBOL_GPL(mlx4_multicast_detach); |
903 | 917 | ||
@@ -905,10 +919,6 @@ int mlx4_unicast_attach(struct mlx4_dev *dev, | |||
905 | struct mlx4_qp *qp, u8 gid[16], | 919 | struct mlx4_qp *qp, u8 gid[16], |
906 | int block_mcast_loopback, enum mlx4_protocol prot) | 920 | int block_mcast_loopback, enum mlx4_protocol prot) |
907 | { | 921 | { |
908 | if (prot == MLX4_PROT_ETH && | ||
909 | !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) | ||
910 | return 0; | ||
911 | |||
912 | if (prot == MLX4_PROT_ETH) | 922 | if (prot == MLX4_PROT_ETH) |
913 | gid[7] |= (MLX4_UC_STEER << 1); | 923 | gid[7] |= (MLX4_UC_STEER << 1); |
914 | 924 | ||
@@ -924,10 +934,6 @@ EXPORT_SYMBOL_GPL(mlx4_unicast_attach); | |||
924 | int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, | 934 | int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, |
925 | u8 gid[16], enum mlx4_protocol prot) | 935 | u8 gid[16], enum mlx4_protocol prot) |
926 | { | 936 | { |
927 | if (prot == MLX4_PROT_ETH && | ||
928 | !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) | ||
929 | return 0; | ||
930 | |||
931 | if (prot == MLX4_PROT_ETH) | 937 | if (prot == MLX4_PROT_ETH) |
932 | gid[7] |= (MLX4_UC_STEER << 1); | 938 | gid[7] |= (MLX4_UC_STEER << 1); |
933 | 939 | ||
@@ -968,9 +974,6 @@ static int mlx4_PROMISC(struct mlx4_dev *dev, u32 qpn, | |||
968 | 974 | ||
969 | int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) | 975 | int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) |
970 | { | 976 | { |
971 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) | ||
972 | return 0; | ||
973 | |||
974 | if (mlx4_is_mfunc(dev)) | 977 | if (mlx4_is_mfunc(dev)) |
975 | return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port); | 978 | return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port); |
976 | 979 | ||
@@ -980,9 +983,6 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add); | |||
980 | 983 | ||
981 | int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) | 984 | int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) |
982 | { | 985 | { |
983 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) | ||
984 | return 0; | ||
985 | |||
986 | if (mlx4_is_mfunc(dev)) | 986 | if (mlx4_is_mfunc(dev)) |
987 | return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port); | 987 | return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port); |
988 | 988 | ||
@@ -992,9 +992,6 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove); | |||
992 | 992 | ||
993 | int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) | 993 | int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) |
994 | { | 994 | { |
995 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) | ||
996 | return 0; | ||
997 | |||
998 | if (mlx4_is_mfunc(dev)) | 995 | if (mlx4_is_mfunc(dev)) |
999 | return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port); | 996 | return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port); |
1000 | 997 | ||
@@ -1004,9 +1001,6 @@ EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add); | |||
1004 | 1001 | ||
1005 | int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) | 1002 | int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) |
1006 | { | 1003 | { |
1007 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) | ||
1008 | return 0; | ||
1009 | |||
1010 | if (mlx4_is_mfunc(dev)) | 1004 | if (mlx4_is_mfunc(dev)) |
1011 | return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port); | 1005 | return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port); |
1012 | 1006 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index a8fb52992c6..58de7237f57 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
@@ -155,7 +155,7 @@ int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn) | |||
155 | return err; | 155 | return err; |
156 | } | 156 | } |
157 | 157 | ||
158 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) { | 158 | if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) { |
159 | *qpn = info->base_qpn + index; | 159 | *qpn = info->base_qpn + index; |
160 | return 0; | 160 | return 0; |
161 | } | 161 | } |
@@ -206,7 +206,7 @@ void mlx4_put_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int qpn) | |||
206 | (unsigned long long) mac); | 206 | (unsigned long long) mac); |
207 | mlx4_unregister_mac(dev, port, mac); | 207 | mlx4_unregister_mac(dev, port, mac); |
208 | 208 | ||
209 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { | 209 | if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) { |
210 | entry = radix_tree_lookup(&info->mac_tree, qpn); | 210 | entry = radix_tree_lookup(&info->mac_tree, qpn); |
211 | if (entry) { | 211 | if (entry) { |
212 | mlx4_dbg(dev, "Releasing qp: port %d, mac 0x%llx," | 212 | mlx4_dbg(dev, "Releasing qp: port %d, mac 0x%llx," |
@@ -359,7 +359,7 @@ int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac) | |||
359 | int index = qpn - info->base_qpn; | 359 | int index = qpn - info->base_qpn; |
360 | int err = 0; | 360 | int err = 0; |
361 | 361 | ||
362 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { | 362 | if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) { |
363 | entry = radix_tree_lookup(&info->mac_tree, qpn); | 363 | entry = radix_tree_lookup(&info->mac_tree, qpn); |
364 | if (!entry) | 364 | if (!entry) |
365 | return -EINVAL; | 365 | return -EINVAL; |
@@ -803,8 +803,7 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, | |||
803 | u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ? | 803 | u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ? |
804 | MCAST_DIRECT : MCAST_DEFAULT; | 804 | MCAST_DIRECT : MCAST_DEFAULT; |
805 | 805 | ||
806 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER && | 806 | if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) |
807 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) | ||
808 | return 0; | 807 | return 0; |
809 | 808 | ||
810 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 809 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 6a8f002b8ed..7f5c9ee42f9 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -70,6 +70,29 @@ enum { | |||
70 | MLX4_MFUNC_EQE_MASK = (MLX4_MFUNC_MAX_EQES - 1) | 70 | MLX4_MFUNC_EQE_MASK = (MLX4_MFUNC_MAX_EQES - 1) |
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* Driver supports 2 diffrent device methods to manage traffic steering: | ||
74 | * - B0 steering mode - Common low level API for ib and (if supported) eth. | ||
75 | * - A0 steering mode - Limited low level API for eth. In case of IB, | ||
76 | * B0 mode is in use. | ||
77 | */ | ||
78 | enum { | ||
79 | MLX4_STEERING_MODE_A0, | ||
80 | MLX4_STEERING_MODE_B0 | ||
81 | }; | ||
82 | |||
83 | static inline const char *mlx4_steering_mode_str(int steering_mode) | ||
84 | { | ||
85 | switch (steering_mode) { | ||
86 | case MLX4_STEERING_MODE_A0: | ||
87 | return "A0 steering"; | ||
88 | |||
89 | case MLX4_STEERING_MODE_B0: | ||
90 | return "B0 steering"; | ||
91 | default: | ||
92 | return "Unrecognize steering mode"; | ||
93 | } | ||
94 | } | ||
95 | |||
73 | enum { | 96 | enum { |
74 | MLX4_DEV_CAP_FLAG_RC = 1LL << 0, | 97 | MLX4_DEV_CAP_FLAG_RC = 1LL << 0, |
75 | MLX4_DEV_CAP_FLAG_UC = 1LL << 1, | 98 | MLX4_DEV_CAP_FLAG_UC = 1LL << 1, |
@@ -295,6 +318,7 @@ struct mlx4_caps { | |||
295 | int num_amgms; | 318 | int num_amgms; |
296 | int reserved_mcgs; | 319 | int reserved_mcgs; |
297 | int num_qp_per_mgm; | 320 | int num_qp_per_mgm; |
321 | int steering_mode; | ||
298 | int num_pds; | 322 | int num_pds; |
299 | int reserved_pds; | 323 | int reserved_pds; |
300 | int max_xrcds; | 324 | int max_xrcds; |