diff options
author | Hadar Hen Zion <hadarh@mellanox.co.il> | 2012-07-05 00:03:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-07 19:23:05 -0400 |
commit | c96d97f4d127b61def87b3ee056bec20cfc265d1 (patch) | |
tree | 84c89ead71dd4f7a0795aa703b60bb5c5eb2d5a4 /drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |
parent | 6d19993788e080edb557178cc6aba2d963edce4e (diff) |
net/mlx4: Set steering mode according to device capabilities
Instead of checking the firmware supported steering mode in various
places in the code, add a dedicated field in the mlx4 device capabilities
structure which is written once during the initialization flow and read
across the code.
This also set the grounds for add new steering modes. Currently two modes
are supported, and are named after the ConnectX HW versions A0 and B0.
A0 steering uses mac_index, vlan_index and priority to steer traffic
into pre-defined range of QPs.
B0 steering uses Ethernet L2 hashing rules and is enabled only
if the firmware supports both unicast and multicast B0 steering,
The current steering modes are relevant for Ethernet traffic only,
such that Infiniband steering remains untouched.
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.co.il>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
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 bedcbb30d38f..44ff7cdb15e5 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; |