diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4/en_netdev.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 108 |
1 files changed, 72 insertions, 36 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; |