aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c108
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c16
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c70
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c9
-rw-r--r--include/linux/mlx4/device.h24
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,
868int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 868int 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}
885EXPORT_SYMBOL_GPL(mlx4_multicast_attach); 892EXPORT_SYMBOL_GPL(mlx4_multicast_attach);
886 893
887int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 894int 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}
902EXPORT_SYMBOL_GPL(mlx4_multicast_detach); 916EXPORT_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);
924int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, 934int 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
969int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 975int 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
981int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 984int 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
993int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 993int 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
1005int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 1002int 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 */
78enum {
79 MLX4_STEERING_MODE_A0,
80 MLX4_STEERING_MODE_B0
81};
82
83static 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
73enum { 96enum {
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;