diff options
author | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
commit | 617677295b53a40d0e54aac4cbbc216ffbc755dd (patch) | |
tree | 51b9e87213243ed5efff252c8e8d8fec4eebc588 /drivers/net/ethernet/mellanox | |
parent | 5c8d1b68e01a144813e38795fe6dbe7ebb506131 (diff) | |
parent | 6abb7c25775b7fb2225ad0508236d63ca710e65f (diff) |
Merge branch 'master' into for-next
Conflicts:
drivers/devfreq/exynos4_bus.c
Sync with Linus' tree to be able to apply patches that are
against newer code (mvneta).
Diffstat (limited to 'drivers/net/ethernet/mellanox')
-rw-r--r-- | drivers/net/ethernet/mellanox/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/Kconfig | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_cq.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 155 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_main.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 29 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_rx.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_tx.c | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/eq.c | 36 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 45 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 171 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mcg.c | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 28 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 28 |
18 files changed, 395 insertions, 168 deletions
diff --git a/drivers/net/ethernet/mellanox/Kconfig b/drivers/net/ethernet/mellanox/Kconfig index d8099a7903d3..bcdbc14aeff0 100644 --- a/drivers/net/ethernet/mellanox/Kconfig +++ b/drivers/net/ethernet/mellanox/Kconfig | |||
@@ -5,7 +5,7 @@ | |||
5 | config NET_VENDOR_MELLANOX | 5 | config NET_VENDOR_MELLANOX |
6 | bool "Mellanox devices" | 6 | bool "Mellanox devices" |
7 | default y | 7 | default y |
8 | depends on PCI && INET | 8 | depends on PCI |
9 | ---help--- | 9 | ---help--- |
10 | If you have a network (Ethernet) card belonging to this class, say Y | 10 | If you have a network (Ethernet) card belonging to this class, say Y |
11 | and read the Ethernet-HOWTO, available from | 11 | and read the Ethernet-HOWTO, available from |
diff --git a/drivers/net/ethernet/mellanox/mlx4/Kconfig b/drivers/net/ethernet/mellanox/mlx4/Kconfig index 5f027f95cc84..eb520ab64014 100644 --- a/drivers/net/ethernet/mellanox/mlx4/Kconfig +++ b/drivers/net/ethernet/mellanox/mlx4/Kconfig | |||
@@ -4,9 +4,8 @@ | |||
4 | 4 | ||
5 | config MLX4_EN | 5 | config MLX4_EN |
6 | tristate "Mellanox Technologies 10Gbit Ethernet support" | 6 | tristate "Mellanox Technologies 10Gbit Ethernet support" |
7 | depends on PCI && INET | 7 | depends on PCI |
8 | select MLX4_CORE | 8 | select MLX4_CORE |
9 | select INET_LRO | ||
10 | ---help--- | 9 | ---help--- |
11 | This driver supports Mellanox Technologies ConnectX Ethernet | 10 | This driver supports Mellanox Technologies ConnectX Ethernet |
12 | devices. | 11 | devices. |
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 3d1899ff1076..fdc5f23d8e9f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -1498,6 +1498,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | |||
1498 | u32 reply; | 1498 | u32 reply; |
1499 | u8 is_going_down = 0; | 1499 | u8 is_going_down = 0; |
1500 | int i; | 1500 | int i; |
1501 | unsigned long flags; | ||
1501 | 1502 | ||
1502 | slave_state[slave].comm_toggle ^= 1; | 1503 | slave_state[slave].comm_toggle ^= 1; |
1503 | reply = (u32) slave_state[slave].comm_toggle << 31; | 1504 | reply = (u32) slave_state[slave].comm_toggle << 31; |
@@ -1576,12 +1577,12 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | |||
1576 | mlx4_warn(dev, "Bad comm cmd:%d from slave:%d\n", cmd, slave); | 1577 | mlx4_warn(dev, "Bad comm cmd:%d from slave:%d\n", cmd, slave); |
1577 | goto reset_slave; | 1578 | goto reset_slave; |
1578 | } | 1579 | } |
1579 | spin_lock(&priv->mfunc.master.slave_state_lock); | 1580 | spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); |
1580 | if (!slave_state[slave].is_slave_going_down) | 1581 | if (!slave_state[slave].is_slave_going_down) |
1581 | slave_state[slave].last_cmd = cmd; | 1582 | slave_state[slave].last_cmd = cmd; |
1582 | else | 1583 | else |
1583 | is_going_down = 1; | 1584 | is_going_down = 1; |
1584 | spin_unlock(&priv->mfunc.master.slave_state_lock); | 1585 | spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); |
1585 | if (is_going_down) { | 1586 | if (is_going_down) { |
1586 | mlx4_warn(dev, "Slave is going down aborting command(%d)" | 1587 | mlx4_warn(dev, "Slave is going down aborting command(%d)" |
1587 | " executing from slave:%d\n", | 1588 | " executing from slave:%d\n", |
@@ -1597,10 +1598,10 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, | |||
1597 | reset_slave: | 1598 | reset_slave: |
1598 | /* cleanup any slave resources */ | 1599 | /* cleanup any slave resources */ |
1599 | mlx4_delete_all_resources_for_slave(dev, slave); | 1600 | mlx4_delete_all_resources_for_slave(dev, slave); |
1600 | spin_lock(&priv->mfunc.master.slave_state_lock); | 1601 | spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); |
1601 | if (!slave_state[slave].is_slave_going_down) | 1602 | if (!slave_state[slave].is_slave_going_down) |
1602 | slave_state[slave].last_cmd = MLX4_COMM_CMD_RESET; | 1603 | slave_state[slave].last_cmd = MLX4_COMM_CMD_RESET; |
1603 | spin_unlock(&priv->mfunc.master.slave_state_lock); | 1604 | spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); |
1604 | /*with slave in the middle of flr, no need to clean resources again.*/ | 1605 | /*with slave in the middle of flr, no need to clean resources again.*/ |
1605 | inform_slave_state: | 1606 | inform_slave_state: |
1606 | memset(&slave_state[slave].event_eq, 0, | 1607 | memset(&slave_state[slave].event_eq, 0, |
@@ -1755,7 +1756,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) | |||
1755 | spin_lock_init(&s_state->lock); | 1756 | spin_lock_init(&s_state->lock); |
1756 | } | 1757 | } |
1757 | 1758 | ||
1758 | memset(&priv->mfunc.master.cmd_eqe, 0, sizeof(struct mlx4_eqe)); | 1759 | memset(&priv->mfunc.master.cmd_eqe, 0, dev->caps.eqe_size); |
1759 | priv->mfunc.master.cmd_eqe.type = MLX4_EVENT_TYPE_CMD; | 1760 | priv->mfunc.master.cmd_eqe.type = MLX4_EVENT_TYPE_CMD; |
1760 | INIT_WORK(&priv->mfunc.master.comm_work, | 1761 | INIT_WORK(&priv->mfunc.master.comm_work, |
1761 | mlx4_master_comm_channel); | 1762 | mlx4_master_comm_channel); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c index aa9c2f6cf3c0..b8d0854a7ad1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c | |||
@@ -51,7 +51,7 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv, | |||
51 | int err; | 51 | int err; |
52 | 52 | ||
53 | cq->size = entries; | 53 | cq->size = entries; |
54 | cq->buf_size = cq->size * sizeof(struct mlx4_cqe); | 54 | cq->buf_size = cq->size * mdev->dev->caps.cqe_size; |
55 | 55 | ||
56 | cq->ring = ring; | 56 | cq->ring = ring; |
57 | cq->is_tx = mode; | 57 | cq->is_tx = mode; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c index 5d36795877cb..b799ab12a291 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c | |||
@@ -237,7 +237,7 @@ static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev, | |||
237 | if (err) | 237 | if (err) |
238 | return err; | 238 | return err; |
239 | 239 | ||
240 | memcpy(priv->maxrate, tmp, sizeof(*priv->maxrate)); | 240 | memcpy(priv->maxrate, tmp, sizeof(priv->maxrate)); |
241 | 241 | ||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 9d0b88eea02b..03447dad07e9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |||
@@ -43,6 +43,34 @@ | |||
43 | #define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff) | 43 | #define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff) |
44 | #define EN_ETHTOOL_WORD_MASK cpu_to_be32(0xffffffff) | 44 | #define EN_ETHTOOL_WORD_MASK cpu_to_be32(0xffffffff) |
45 | 45 | ||
46 | static int mlx4_en_moderation_update(struct mlx4_en_priv *priv) | ||
47 | { | ||
48 | int i; | ||
49 | int err = 0; | ||
50 | |||
51 | for (i = 0; i < priv->tx_ring_num; i++) { | ||
52 | priv->tx_cq[i].moder_cnt = priv->tx_frames; | ||
53 | priv->tx_cq[i].moder_time = priv->tx_usecs; | ||
54 | err = mlx4_en_set_cq_moder(priv, &priv->tx_cq[i]); | ||
55 | if (err) | ||
56 | return err; | ||
57 | } | ||
58 | |||
59 | if (priv->adaptive_rx_coal) | ||
60 | return 0; | ||
61 | |||
62 | for (i = 0; i < priv->rx_ring_num; i++) { | ||
63 | priv->rx_cq[i].moder_cnt = priv->rx_frames; | ||
64 | priv->rx_cq[i].moder_time = priv->rx_usecs; | ||
65 | priv->last_moder_time[i] = MLX4_EN_AUTO_CONF; | ||
66 | err = mlx4_en_set_cq_moder(priv, &priv->rx_cq[i]); | ||
67 | if (err) | ||
68 | return err; | ||
69 | } | ||
70 | |||
71 | return err; | ||
72 | } | ||
73 | |||
46 | static void | 74 | static void |
47 | mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) | 75 | mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) |
48 | { | 76 | { |
@@ -381,7 +409,6 @@ static int mlx4_en_set_coalesce(struct net_device *dev, | |||
381 | struct ethtool_coalesce *coal) | 409 | struct ethtool_coalesce *coal) |
382 | { | 410 | { |
383 | struct mlx4_en_priv *priv = netdev_priv(dev); | 411 | struct mlx4_en_priv *priv = netdev_priv(dev); |
384 | int err, i; | ||
385 | 412 | ||
386 | priv->rx_frames = (coal->rx_max_coalesced_frames == | 413 | priv->rx_frames = (coal->rx_max_coalesced_frames == |
387 | MLX4_EN_AUTO_CONF) ? | 414 | MLX4_EN_AUTO_CONF) ? |
@@ -397,14 +424,6 @@ static int mlx4_en_set_coalesce(struct net_device *dev, | |||
397 | coal->tx_max_coalesced_frames != priv->tx_frames) { | 424 | coal->tx_max_coalesced_frames != priv->tx_frames) { |
398 | priv->tx_usecs = coal->tx_coalesce_usecs; | 425 | priv->tx_usecs = coal->tx_coalesce_usecs; |
399 | priv->tx_frames = coal->tx_max_coalesced_frames; | 426 | priv->tx_frames = coal->tx_max_coalesced_frames; |
400 | for (i = 0; i < priv->tx_ring_num; i++) { | ||
401 | priv->tx_cq[i].moder_cnt = priv->tx_frames; | ||
402 | priv->tx_cq[i].moder_time = priv->tx_usecs; | ||
403 | if (mlx4_en_set_cq_moder(priv, &priv->tx_cq[i])) { | ||
404 | en_warn(priv, "Failed changing moderation " | ||
405 | "for TX cq %d\n", i); | ||
406 | } | ||
407 | } | ||
408 | } | 427 | } |
409 | 428 | ||
410 | /* Set adaptive coalescing params */ | 429 | /* Set adaptive coalescing params */ |
@@ -414,18 +433,8 @@ static int mlx4_en_set_coalesce(struct net_device *dev, | |||
414 | priv->rx_usecs_high = coal->rx_coalesce_usecs_high; | 433 | priv->rx_usecs_high = coal->rx_coalesce_usecs_high; |
415 | priv->sample_interval = coal->rate_sample_interval; | 434 | priv->sample_interval = coal->rate_sample_interval; |
416 | priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce; | 435 | priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce; |
417 | if (priv->adaptive_rx_coal) | ||
418 | return 0; | ||
419 | 436 | ||
420 | for (i = 0; i < priv->rx_ring_num; i++) { | 437 | return mlx4_en_moderation_update(priv); |
421 | priv->rx_cq[i].moder_cnt = priv->rx_frames; | ||
422 | priv->rx_cq[i].moder_time = priv->rx_usecs; | ||
423 | priv->last_moder_time[i] = MLX4_EN_AUTO_CONF; | ||
424 | err = mlx4_en_set_cq_moder(priv, &priv->rx_cq[i]); | ||
425 | if (err) | ||
426 | return err; | ||
427 | } | ||
428 | return 0; | ||
429 | } | 438 | } |
430 | 439 | ||
431 | static int mlx4_en_set_pauseparam(struct net_device *dev, | 440 | static int mlx4_en_set_pauseparam(struct net_device *dev, |
@@ -466,7 +475,6 @@ static int mlx4_en_set_ringparam(struct net_device *dev, | |||
466 | u32 rx_size, tx_size; | 475 | u32 rx_size, tx_size; |
467 | int port_up = 0; | 476 | int port_up = 0; |
468 | int err = 0; | 477 | int err = 0; |
469 | int i; | ||
470 | 478 | ||
471 | if (param->rx_jumbo_pending || param->rx_mini_pending) | 479 | if (param->rx_jumbo_pending || param->rx_mini_pending) |
472 | return -EINVAL; | 480 | return -EINVAL; |
@@ -505,14 +513,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev, | |||
505 | en_err(priv, "Failed starting port\n"); | 513 | en_err(priv, "Failed starting port\n"); |
506 | } | 514 | } |
507 | 515 | ||
508 | for (i = 0; i < priv->rx_ring_num; i++) { | 516 | err = mlx4_en_moderation_update(priv); |
509 | priv->rx_cq[i].moder_cnt = priv->rx_frames; | ||
510 | priv->rx_cq[i].moder_time = priv->rx_usecs; | ||
511 | priv->last_moder_time[i] = MLX4_EN_AUTO_CONF; | ||
512 | err = mlx4_en_set_cq_moder(priv, &priv->rx_cq[i]); | ||
513 | if (err) | ||
514 | goto out; | ||
515 | } | ||
516 | 517 | ||
517 | out: | 518 | out: |
518 | mutex_unlock(&mdev->state_lock); | 519 | mutex_unlock(&mdev->state_lock); |
@@ -612,13 +613,17 @@ static int mlx4_en_validate_flow(struct net_device *dev, | |||
612 | struct ethtool_usrip4_spec *l3_mask; | 613 | struct ethtool_usrip4_spec *l3_mask; |
613 | struct ethtool_tcpip4_spec *l4_mask; | 614 | struct ethtool_tcpip4_spec *l4_mask; |
614 | struct ethhdr *eth_mask; | 615 | struct ethhdr *eth_mask; |
615 | u64 full_mac = ~0ull; | ||
616 | u64 zero_mac = 0; | ||
617 | 616 | ||
618 | if (cmd->fs.location >= MAX_NUM_OF_FS_RULES) | 617 | if (cmd->fs.location >= MAX_NUM_OF_FS_RULES) |
619 | return -EINVAL; | 618 | return -EINVAL; |
620 | 619 | ||
621 | switch (cmd->fs.flow_type & ~FLOW_EXT) { | 620 | if (cmd->fs.flow_type & FLOW_MAC_EXT) { |
621 | /* dest mac mask must be ff:ff:ff:ff:ff:ff */ | ||
622 | if (!is_broadcast_ether_addr(cmd->fs.m_ext.h_dest)) | ||
623 | return -EINVAL; | ||
624 | } | ||
625 | |||
626 | switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { | ||
622 | case TCP_V4_FLOW: | 627 | case TCP_V4_FLOW: |
623 | case UDP_V4_FLOW: | 628 | case UDP_V4_FLOW: |
624 | if (cmd->fs.m_u.tcp_ip4_spec.tos) | 629 | if (cmd->fs.m_u.tcp_ip4_spec.tos) |
@@ -643,11 +648,11 @@ static int mlx4_en_validate_flow(struct net_device *dev, | |||
643 | case ETHER_FLOW: | 648 | case ETHER_FLOW: |
644 | eth_mask = &cmd->fs.m_u.ether_spec; | 649 | eth_mask = &cmd->fs.m_u.ether_spec; |
645 | /* source mac mask must not be set */ | 650 | /* source mac mask must not be set */ |
646 | if (memcmp(eth_mask->h_source, &zero_mac, ETH_ALEN)) | 651 | if (!is_zero_ether_addr(eth_mask->h_source)) |
647 | return -EINVAL; | 652 | return -EINVAL; |
648 | 653 | ||
649 | /* dest mac mask must be ff:ff:ff:ff:ff:ff */ | 654 | /* dest mac mask must be ff:ff:ff:ff:ff:ff */ |
650 | if (memcmp(eth_mask->h_dest, &full_mac, ETH_ALEN)) | 655 | if (!is_broadcast_ether_addr(eth_mask->h_dest)) |
651 | return -EINVAL; | 656 | return -EINVAL; |
652 | 657 | ||
653 | if (!all_zeros_or_all_ones(eth_mask->h_proto)) | 658 | if (!all_zeros_or_all_ones(eth_mask->h_proto)) |
@@ -746,7 +751,6 @@ static int mlx4_en_ethtool_to_net_trans_rule(struct net_device *dev, | |||
746 | struct list_head *rule_list_h) | 751 | struct list_head *rule_list_h) |
747 | { | 752 | { |
748 | int err; | 753 | int err; |
749 | u64 mac; | ||
750 | __be64 be_mac; | 754 | __be64 be_mac; |
751 | struct ethhdr *eth_spec; | 755 | struct ethhdr *eth_spec; |
752 | struct mlx4_en_priv *priv = netdev_priv(dev); | 756 | struct mlx4_en_priv *priv = netdev_priv(dev); |
@@ -761,12 +765,16 @@ static int mlx4_en_ethtool_to_net_trans_rule(struct net_device *dev, | |||
761 | if (!spec_l2) | 765 | if (!spec_l2) |
762 | return -ENOMEM; | 766 | return -ENOMEM; |
763 | 767 | ||
764 | mac = priv->mac & MLX4_MAC_MASK; | 768 | if (cmd->fs.flow_type & FLOW_MAC_EXT) { |
765 | be_mac = cpu_to_be64(mac << 16); | 769 | memcpy(&be_mac, cmd->fs.h_ext.h_dest, ETH_ALEN); |
770 | } else { | ||
771 | u64 mac = priv->mac & MLX4_MAC_MASK; | ||
772 | be_mac = cpu_to_be64(mac << 16); | ||
773 | } | ||
766 | 774 | ||
767 | spec_l2->id = MLX4_NET_TRANS_RULE_ID_ETH; | 775 | spec_l2->id = MLX4_NET_TRANS_RULE_ID_ETH; |
768 | memcpy(spec_l2->eth.dst_mac_msk, &mac_msk, ETH_ALEN); | 776 | memcpy(spec_l2->eth.dst_mac_msk, &mac_msk, ETH_ALEN); |
769 | if ((cmd->fs.flow_type & ~FLOW_EXT) != ETHER_FLOW) | 777 | if ((cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) != ETHER_FLOW) |
770 | memcpy(spec_l2->eth.dst_mac, &be_mac, ETH_ALEN); | 778 | memcpy(spec_l2->eth.dst_mac, &be_mac, ETH_ALEN); |
771 | 779 | ||
772 | if ((cmd->fs.flow_type & FLOW_EXT) && cmd->fs.m_ext.vlan_tci) { | 780 | if ((cmd->fs.flow_type & FLOW_EXT) && cmd->fs.m_ext.vlan_tci) { |
@@ -776,7 +784,7 @@ static int mlx4_en_ethtool_to_net_trans_rule(struct net_device *dev, | |||
776 | 784 | ||
777 | list_add_tail(&spec_l2->list, rule_list_h); | 785 | list_add_tail(&spec_l2->list, rule_list_h); |
778 | 786 | ||
779 | switch (cmd->fs.flow_type & ~FLOW_EXT) { | 787 | switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { |
780 | case ETHER_FLOW: | 788 | case ETHER_FLOW: |
781 | eth_spec = &cmd->fs.h_u.ether_spec; | 789 | eth_spec = &cmd->fs.h_u.ether_spec; |
782 | memcpy(&spec_l2->eth.dst_mac, eth_spec->h_dest, ETH_ALEN); | 790 | memcpy(&spec_l2->eth.dst_mac, eth_spec->h_dest, ETH_ALEN); |
@@ -998,6 +1006,73 @@ static int mlx4_en_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) | |||
998 | return err; | 1006 | return err; |
999 | } | 1007 | } |
1000 | 1008 | ||
1009 | static void mlx4_en_get_channels(struct net_device *dev, | ||
1010 | struct ethtool_channels *channel) | ||
1011 | { | ||
1012 | struct mlx4_en_priv *priv = netdev_priv(dev); | ||
1013 | |||
1014 | memset(channel, 0, sizeof(*channel)); | ||
1015 | |||
1016 | channel->max_rx = MAX_RX_RINGS; | ||
1017 | channel->max_tx = MLX4_EN_MAX_TX_RING_P_UP; | ||
1018 | |||
1019 | channel->rx_count = priv->rx_ring_num; | ||
1020 | channel->tx_count = priv->tx_ring_num / MLX4_EN_NUM_UP; | ||
1021 | } | ||
1022 | |||
1023 | static int mlx4_en_set_channels(struct net_device *dev, | ||
1024 | struct ethtool_channels *channel) | ||
1025 | { | ||
1026 | struct mlx4_en_priv *priv = netdev_priv(dev); | ||
1027 | struct mlx4_en_dev *mdev = priv->mdev; | ||
1028 | int port_up; | ||
1029 | int err = 0; | ||
1030 | |||
1031 | if (channel->other_count || channel->combined_count || | ||
1032 | channel->tx_count > MLX4_EN_MAX_TX_RING_P_UP || | ||
1033 | channel->rx_count > MAX_RX_RINGS || | ||
1034 | !channel->tx_count || !channel->rx_count) | ||
1035 | return -EINVAL; | ||
1036 | |||
1037 | mutex_lock(&mdev->state_lock); | ||
1038 | if (priv->port_up) { | ||
1039 | port_up = 1; | ||
1040 | mlx4_en_stop_port(dev); | ||
1041 | } | ||
1042 | |||
1043 | mlx4_en_free_resources(priv); | ||
1044 | |||
1045 | priv->num_tx_rings_p_up = channel->tx_count; | ||
1046 | priv->tx_ring_num = channel->tx_count * MLX4_EN_NUM_UP; | ||
1047 | priv->rx_ring_num = channel->rx_count; | ||
1048 | |||
1049 | err = mlx4_en_alloc_resources(priv); | ||
1050 | if (err) { | ||
1051 | en_err(priv, "Failed reallocating port resources\n"); | ||
1052 | goto out; | ||
1053 | } | ||
1054 | |||
1055 | netif_set_real_num_tx_queues(dev, priv->tx_ring_num); | ||
1056 | netif_set_real_num_rx_queues(dev, priv->rx_ring_num); | ||
1057 | |||
1058 | mlx4_en_setup_tc(dev, MLX4_EN_NUM_UP); | ||
1059 | |||
1060 | en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num); | ||
1061 | en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num); | ||
1062 | |||
1063 | if (port_up) { | ||
1064 | err = mlx4_en_start_port(dev); | ||
1065 | if (err) | ||
1066 | en_err(priv, "Failed starting port\n"); | ||
1067 | } | ||
1068 | |||
1069 | err = mlx4_en_moderation_update(priv); | ||
1070 | |||
1071 | out: | ||
1072 | mutex_unlock(&mdev->state_lock); | ||
1073 | return err; | ||
1074 | } | ||
1075 | |||
1001 | const struct ethtool_ops mlx4_en_ethtool_ops = { | 1076 | const struct ethtool_ops mlx4_en_ethtool_ops = { |
1002 | .get_drvinfo = mlx4_en_get_drvinfo, | 1077 | .get_drvinfo = mlx4_en_get_drvinfo, |
1003 | .get_settings = mlx4_en_get_settings, | 1078 | .get_settings = mlx4_en_get_settings, |
@@ -1022,6 +1097,8 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { | |||
1022 | .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size, | 1097 | .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size, |
1023 | .get_rxfh_indir = mlx4_en_get_rxfh_indir, | 1098 | .get_rxfh_indir = mlx4_en_get_rxfh_indir, |
1024 | .set_rxfh_indir = mlx4_en_set_rxfh_indir, | 1099 | .set_rxfh_indir = mlx4_en_set_rxfh_indir, |
1100 | .get_channels = mlx4_en_get_channels, | ||
1101 | .set_channels = mlx4_en_set_channels, | ||
1025 | }; | 1102 | }; |
1026 | 1103 | ||
1027 | 1104 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c index d09b0d9ca68b..8611c89f034d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c | |||
@@ -250,7 +250,7 @@ static void *mlx4_en_add(struct mlx4_dev *dev) | |||
250 | rounddown_pow_of_two(max_t(int, MIN_RX_RINGS, | 250 | rounddown_pow_of_two(max_t(int, MIN_RX_RINGS, |
251 | min_t(int, | 251 | min_t(int, |
252 | dev->caps.num_comp_vectors, | 252 | dev->caps.num_comp_vectors, |
253 | MAX_RX_RINGS))); | 253 | DEF_RX_RINGS))); |
254 | } else { | 254 | } else { |
255 | mdev->profile.prof[i].rx_ring_num = rounddown_pow_of_two( | 255 | mdev->profile.prof[i].rx_ring_num = rounddown_pow_of_two( |
256 | min_t(int, dev->caps.comp_pool/ | 256 | min_t(int, dev->caps.comp_pool/ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index edd9cb8d3e1d..75a3f467bb5b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -47,11 +47,11 @@ | |||
47 | #include "mlx4_en.h" | 47 | #include "mlx4_en.h" |
48 | #include "en_port.h" | 48 | #include "en_port.h" |
49 | 49 | ||
50 | static int mlx4_en_setup_tc(struct net_device *dev, u8 up) | 50 | int mlx4_en_setup_tc(struct net_device *dev, u8 up) |
51 | { | 51 | { |
52 | struct mlx4_en_priv *priv = netdev_priv(dev); | 52 | struct mlx4_en_priv *priv = netdev_priv(dev); |
53 | int i; | 53 | int i; |
54 | unsigned int q, offset = 0; | 54 | unsigned int offset = 0; |
55 | 55 | ||
56 | if (up && up != MLX4_EN_NUM_UP) | 56 | if (up && up != MLX4_EN_NUM_UP) |
57 | return -EINVAL; | 57 | return -EINVAL; |
@@ -59,10 +59,9 @@ static int mlx4_en_setup_tc(struct net_device *dev, u8 up) | |||
59 | netdev_set_num_tc(dev, up); | 59 | netdev_set_num_tc(dev, up); |
60 | 60 | ||
61 | /* Partition Tx queues evenly amongst UP's */ | 61 | /* Partition Tx queues evenly amongst UP's */ |
62 | q = priv->tx_ring_num / up; | ||
63 | for (i = 0; i < up; i++) { | 62 | for (i = 0; i < up; i++) { |
64 | netdev_set_tc_queue(dev, i, q, offset); | 63 | netdev_set_tc_queue(dev, i, priv->num_tx_rings_p_up, offset); |
65 | offset += q; | 64 | offset += priv->num_tx_rings_p_up; |
66 | } | 65 | } |
67 | 66 | ||
68 | return 0; | 67 | return 0; |
@@ -870,7 +869,7 @@ static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv) | |||
870 | /* If we haven't received a specific coalescing setting | 869 | /* If we haven't received a specific coalescing setting |
871 | * (module param), we set the moderation parameters as follows: | 870 | * (module param), we set the moderation parameters as follows: |
872 | * - moder_cnt is set to the number of mtu sized packets to | 871 | * - moder_cnt is set to the number of mtu sized packets to |
873 | * satisfy our coelsing target. | 872 | * satisfy our coalescing target. |
874 | * - moder_time is set to a fixed value. | 873 | * - moder_time is set to a fixed value. |
875 | */ | 874 | */ |
876 | priv->rx_frames = MLX4_EN_RX_COAL_TARGET; | 875 | priv->rx_frames = MLX4_EN_RX_COAL_TARGET; |
@@ -1114,7 +1113,7 @@ int mlx4_en_start_port(struct net_device *dev) | |||
1114 | /* Configure ring */ | 1113 | /* Configure ring */ |
1115 | tx_ring = &priv->tx_ring[i]; | 1114 | tx_ring = &priv->tx_ring[i]; |
1116 | err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn, | 1115 | err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn, |
1117 | i / priv->mdev->profile.num_tx_rings_p_up); | 1116 | i / priv->num_tx_rings_p_up); |
1118 | if (err) { | 1117 | if (err) { |
1119 | en_err(priv, "Failed allocating Tx ring\n"); | 1118 | en_err(priv, "Failed allocating Tx ring\n"); |
1120 | mlx4_en_deactivate_cq(priv, cq); | 1119 | mlx4_en_deactivate_cq(priv, cq); |
@@ -1564,10 +1563,13 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
1564 | int err; | 1563 | int err; |
1565 | 1564 | ||
1566 | dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv), | 1565 | dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv), |
1567 | prof->tx_ring_num, prof->rx_ring_num); | 1566 | MAX_TX_RINGS, MAX_RX_RINGS); |
1568 | if (dev == NULL) | 1567 | if (dev == NULL) |
1569 | return -ENOMEM; | 1568 | return -ENOMEM; |
1570 | 1569 | ||
1570 | netif_set_real_num_tx_queues(dev, prof->tx_ring_num); | ||
1571 | netif_set_real_num_rx_queues(dev, prof->rx_ring_num); | ||
1572 | |||
1571 | SET_NETDEV_DEV(dev, &mdev->dev->pdev->dev); | 1573 | SET_NETDEV_DEV(dev, &mdev->dev->pdev->dev); |
1572 | dev->dev_id = port - 1; | 1574 | dev->dev_id = port - 1; |
1573 | 1575 | ||
@@ -1586,20 +1588,23 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
1586 | priv->flags = prof->flags; | 1588 | priv->flags = prof->flags; |
1587 | priv->ctrl_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE | | 1589 | priv->ctrl_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE | |
1588 | MLX4_WQE_CTRL_SOLICITED); | 1590 | MLX4_WQE_CTRL_SOLICITED); |
1591 | priv->num_tx_rings_p_up = mdev->profile.num_tx_rings_p_up; | ||
1589 | priv->tx_ring_num = prof->tx_ring_num; | 1592 | priv->tx_ring_num = prof->tx_ring_num; |
1590 | priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring) * | 1593 | |
1591 | priv->tx_ring_num, GFP_KERNEL); | 1594 | priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring) * MAX_TX_RINGS, |
1595 | GFP_KERNEL); | ||
1592 | if (!priv->tx_ring) { | 1596 | if (!priv->tx_ring) { |
1593 | err = -ENOMEM; | 1597 | err = -ENOMEM; |
1594 | goto out; | 1598 | goto out; |
1595 | } | 1599 | } |
1596 | priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * priv->tx_ring_num, | 1600 | priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * MAX_RX_RINGS, |
1597 | GFP_KERNEL); | 1601 | GFP_KERNEL); |
1598 | if (!priv->tx_cq) { | 1602 | if (!priv->tx_cq) { |
1599 | err = -ENOMEM; | 1603 | err = -ENOMEM; |
1600 | goto out; | 1604 | goto out; |
1601 | } | 1605 | } |
1602 | priv->rx_ring_num = prof->rx_ring_num; | 1606 | priv->rx_ring_num = prof->rx_ring_num; |
1607 | priv->cqe_factor = (mdev->dev->caps.cqe_size == 64) ? 1 : 0; | ||
1603 | priv->mac_index = -1; | 1608 | priv->mac_index = -1; |
1604 | priv->msg_enable = MLX4_EN_MSG_LEVEL; | 1609 | priv->msg_enable = MLX4_EN_MSG_LEVEL; |
1605 | spin_lock_init(&priv->stats_lock); | 1610 | spin_lock_init(&priv->stats_lock); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 5aba5ecdf1e2..fed26d867f4e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c | |||
@@ -566,6 +566,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud | |||
566 | struct ethhdr *ethh; | 566 | struct ethhdr *ethh; |
567 | dma_addr_t dma; | 567 | dma_addr_t dma; |
568 | u64 s_mac; | 568 | u64 s_mac; |
569 | int factor = priv->cqe_factor; | ||
569 | 570 | ||
570 | if (!priv->port_up) | 571 | if (!priv->port_up) |
571 | return 0; | 572 | return 0; |
@@ -574,7 +575,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud | |||
574 | * descriptor offset can be deduced from the CQE index instead of | 575 | * descriptor offset can be deduced from the CQE index instead of |
575 | * reading 'cqe->index' */ | 576 | * reading 'cqe->index' */ |
576 | index = cq->mcq.cons_index & ring->size_mask; | 577 | index = cq->mcq.cons_index & ring->size_mask; |
577 | cqe = &cq->buf[index]; | 578 | cqe = &cq->buf[(index << factor) + factor]; |
578 | 579 | ||
579 | /* Process all completed CQEs */ | 580 | /* Process all completed CQEs */ |
580 | while (XNOR(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK, | 581 | while (XNOR(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK, |
@@ -630,7 +631,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud | |||
630 | if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) && | 631 | if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) && |
631 | (cqe->checksum == cpu_to_be16(0xffff))) { | 632 | (cqe->checksum == cpu_to_be16(0xffff))) { |
632 | ring->csum_ok++; | 633 | ring->csum_ok++; |
633 | /* This packet is eligible for LRO if it is: | 634 | /* This packet is eligible for GRO if it is: |
634 | * - DIX Ethernet (type interpretation) | 635 | * - DIX Ethernet (type interpretation) |
635 | * - TCP/IP (v4) | 636 | * - TCP/IP (v4) |
636 | * - without IP options | 637 | * - without IP options |
@@ -667,7 +668,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud | |||
667 | goto next; | 668 | goto next; |
668 | } | 669 | } |
669 | 670 | ||
670 | /* LRO not possible, complete processing here */ | 671 | /* GRO not possible, complete processing here */ |
671 | ip_summed = CHECKSUM_UNNECESSARY; | 672 | ip_summed = CHECKSUM_UNNECESSARY; |
672 | } else { | 673 | } else { |
673 | ip_summed = CHECKSUM_NONE; | 674 | ip_summed = CHECKSUM_NONE; |
@@ -709,12 +710,9 @@ next: | |||
709 | 710 | ||
710 | ++cq->mcq.cons_index; | 711 | ++cq->mcq.cons_index; |
711 | index = (cq->mcq.cons_index) & ring->size_mask; | 712 | index = (cq->mcq.cons_index) & ring->size_mask; |
712 | cqe = &cq->buf[index]; | 713 | cqe = &cq->buf[(index << factor) + factor]; |
713 | if (++polled == budget) { | 714 | if (++polled == budget) |
714 | /* We are here because we reached the NAPI budget - | ||
715 | * flush only pending LRO sessions */ | ||
716 | goto out; | 715 | goto out; |
717 | } | ||
718 | } | 716 | } |
719 | 717 | ||
720 | out: | 718 | out: |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index b35094c590ba..6771b69f40d5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -315,12 +315,13 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) | |||
315 | struct mlx4_cqe *buf = cq->buf; | 315 | struct mlx4_cqe *buf = cq->buf; |
316 | u32 packets = 0; | 316 | u32 packets = 0; |
317 | u32 bytes = 0; | 317 | u32 bytes = 0; |
318 | int factor = priv->cqe_factor; | ||
318 | 319 | ||
319 | if (!priv->port_up) | 320 | if (!priv->port_up) |
320 | return; | 321 | return; |
321 | 322 | ||
322 | index = cons_index & size_mask; | 323 | index = cons_index & size_mask; |
323 | cqe = &buf[index]; | 324 | cqe = &buf[(index << factor) + factor]; |
324 | ring_index = ring->cons & size_mask; | 325 | ring_index = ring->cons & size_mask; |
325 | 326 | ||
326 | /* Process all completed CQEs */ | 327 | /* Process all completed CQEs */ |
@@ -349,7 +350,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) | |||
349 | 350 | ||
350 | ++cons_index; | 351 | ++cons_index; |
351 | index = cons_index & size_mask; | 352 | index = cons_index & size_mask; |
352 | cqe = &buf[index]; | 353 | cqe = &buf[(index << factor) + factor]; |
353 | } | 354 | } |
354 | 355 | ||
355 | 356 | ||
@@ -523,7 +524,7 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk | |||
523 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb) | 524 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb) |
524 | { | 525 | { |
525 | struct mlx4_en_priv *priv = netdev_priv(dev); | 526 | struct mlx4_en_priv *priv = netdev_priv(dev); |
526 | u16 rings_p_up = priv->mdev->profile.num_tx_rings_p_up; | 527 | u16 rings_p_up = priv->num_tx_rings_p_up; |
527 | u8 up = 0; | 528 | u8 up = 0; |
528 | 529 | ||
529 | if (dev->num_tc) | 530 | if (dev->num_tc) |
@@ -629,10 +630,15 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
629 | ring->tx_csum++; | 630 | ring->tx_csum++; |
630 | } | 631 | } |
631 | 632 | ||
632 | /* Copy dst mac address to wqe */ | 633 | if (mlx4_is_mfunc(mdev->dev) || priv->validate_loopback) { |
633 | ethh = (struct ethhdr *)skb->data; | 634 | /* Copy dst mac address to wqe. This allows loopback in eSwitch, |
634 | tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest); | 635 | * so that VFs and PF can communicate with each other |
635 | tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2)); | 636 | */ |
637 | ethh = (struct ethhdr *)skb->data; | ||
638 | tx_desc->ctrl.srcrb_flags16[0] = get_unaligned((__be16 *)ethh->h_dest); | ||
639 | tx_desc->ctrl.imm = get_unaligned((__be32 *)(ethh->h_dest + 2)); | ||
640 | } | ||
641 | |||
636 | /* Handle LSO (TSO) packets */ | 642 | /* Handle LSO (TSO) packets */ |
637 | if (lso_header_size) { | 643 | if (lso_header_size) { |
638 | /* Mark opcode as LSO */ | 644 | /* Mark opcode as LSO */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index c48cf6f6529c..251ae2f93116 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
@@ -101,15 +101,21 @@ static void eq_set_ci(struct mlx4_eq *eq, int req_not) | |||
101 | mb(); | 101 | mb(); |
102 | } | 102 | } |
103 | 103 | ||
104 | static struct mlx4_eqe *get_eqe(struct mlx4_eq *eq, u32 entry) | 104 | static struct mlx4_eqe *get_eqe(struct mlx4_eq *eq, u32 entry, u8 eqe_factor) |
105 | { | 105 | { |
106 | unsigned long off = (entry & (eq->nent - 1)) * MLX4_EQ_ENTRY_SIZE; | 106 | /* (entry & (eq->nent - 1)) gives us a cyclic array */ |
107 | return eq->page_list[off / PAGE_SIZE].buf + off % PAGE_SIZE; | 107 | unsigned long offset = (entry & (eq->nent - 1)) * (MLX4_EQ_ENTRY_SIZE << eqe_factor); |
108 | /* CX3 is capable of extending the EQE from 32 to 64 bytes. | ||
109 | * When this feature is enabled, the first (in the lower addresses) | ||
110 | * 32 bytes in the 64 byte EQE are reserved and the next 32 bytes | ||
111 | * contain the legacy EQE information. | ||
112 | */ | ||
113 | return eq->page_list[offset / PAGE_SIZE].buf + (offset + (eqe_factor ? MLX4_EQ_ENTRY_SIZE : 0)) % PAGE_SIZE; | ||
108 | } | 114 | } |
109 | 115 | ||
110 | static struct mlx4_eqe *next_eqe_sw(struct mlx4_eq *eq) | 116 | static struct mlx4_eqe *next_eqe_sw(struct mlx4_eq *eq, u8 eqe_factor) |
111 | { | 117 | { |
112 | struct mlx4_eqe *eqe = get_eqe(eq, eq->cons_index); | 118 | struct mlx4_eqe *eqe = get_eqe(eq, eq->cons_index, eqe_factor); |
113 | return !!(eqe->owner & 0x80) ^ !!(eq->cons_index & eq->nent) ? NULL : eqe; | 119 | return !!(eqe->owner & 0x80) ^ !!(eq->cons_index & eq->nent) ? NULL : eqe; |
114 | } | 120 | } |
115 | 121 | ||
@@ -177,7 +183,7 @@ static void slave_event(struct mlx4_dev *dev, u8 slave, struct mlx4_eqe *eqe) | |||
177 | return; | 183 | return; |
178 | } | 184 | } |
179 | 185 | ||
180 | memcpy(s_eqe, eqe, sizeof(struct mlx4_eqe) - 1); | 186 | memcpy(s_eqe, eqe, dev->caps.eqe_size - 1); |
181 | s_eqe->slave_id = slave; | 187 | s_eqe->slave_id = slave; |
182 | /* ensure all information is written before setting the ownersip bit */ | 188 | /* ensure all information is written before setting the ownersip bit */ |
183 | wmb(); | 189 | wmb(); |
@@ -401,6 +407,7 @@ void mlx4_master_handle_slave_flr(struct work_struct *work) | |||
401 | struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state; | 407 | struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state; |
402 | int i; | 408 | int i; |
403 | int err; | 409 | int err; |
410 | unsigned long flags; | ||
404 | 411 | ||
405 | mlx4_dbg(dev, "mlx4_handle_slave_flr\n"); | 412 | mlx4_dbg(dev, "mlx4_handle_slave_flr\n"); |
406 | 413 | ||
@@ -412,10 +419,10 @@ void mlx4_master_handle_slave_flr(struct work_struct *work) | |||
412 | 419 | ||
413 | mlx4_delete_all_resources_for_slave(dev, i); | 420 | mlx4_delete_all_resources_for_slave(dev, i); |
414 | /*return the slave to running mode*/ | 421 | /*return the slave to running mode*/ |
415 | spin_lock(&priv->mfunc.master.slave_state_lock); | 422 | spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); |
416 | slave_state[i].last_cmd = MLX4_COMM_CMD_RESET; | 423 | slave_state[i].last_cmd = MLX4_COMM_CMD_RESET; |
417 | slave_state[i].is_slave_going_down = 0; | 424 | slave_state[i].is_slave_going_down = 0; |
418 | spin_unlock(&priv->mfunc.master.slave_state_lock); | 425 | spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); |
419 | /*notify the FW:*/ | 426 | /*notify the FW:*/ |
420 | err = mlx4_cmd(dev, 0, i, 0, MLX4_CMD_INFORM_FLR_DONE, | 427 | err = mlx4_cmd(dev, 0, i, 0, MLX4_CMD_INFORM_FLR_DONE, |
421 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); | 428 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); |
@@ -440,8 +447,9 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) | |||
440 | u8 update_slave_state; | 447 | u8 update_slave_state; |
441 | int i; | 448 | int i; |
442 | enum slave_port_gen_event gen_event; | 449 | enum slave_port_gen_event gen_event; |
450 | unsigned long flags; | ||
443 | 451 | ||
444 | while ((eqe = next_eqe_sw(eq))) { | 452 | while ((eqe = next_eqe_sw(eq, dev->caps.eqe_factor))) { |
445 | /* | 453 | /* |
446 | * Make sure we read EQ entry contents after we've | 454 | * Make sure we read EQ entry contents after we've |
447 | * checked the ownership bit. | 455 | * checked the ownership bit. |
@@ -647,13 +655,13 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) | |||
647 | } else | 655 | } else |
648 | update_slave_state = 1; | 656 | update_slave_state = 1; |
649 | 657 | ||
650 | spin_lock(&priv->mfunc.master.slave_state_lock); | 658 | spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags); |
651 | if (update_slave_state) { | 659 | if (update_slave_state) { |
652 | priv->mfunc.master.slave_state[flr_slave].active = false; | 660 | priv->mfunc.master.slave_state[flr_slave].active = false; |
653 | priv->mfunc.master.slave_state[flr_slave].last_cmd = MLX4_COMM_CMD_FLR; | 661 | priv->mfunc.master.slave_state[flr_slave].last_cmd = MLX4_COMM_CMD_FLR; |
654 | priv->mfunc.master.slave_state[flr_slave].is_slave_going_down = 1; | 662 | priv->mfunc.master.slave_state[flr_slave].is_slave_going_down = 1; |
655 | } | 663 | } |
656 | spin_unlock(&priv->mfunc.master.slave_state_lock); | 664 | spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags); |
657 | queue_work(priv->mfunc.master.comm_wq, | 665 | queue_work(priv->mfunc.master.comm_wq, |
658 | &priv->mfunc.master.slave_flr_event_work); | 666 | &priv->mfunc.master.slave_flr_event_work); |
659 | break; | 667 | break; |
@@ -864,7 +872,8 @@ static int mlx4_create_eq(struct mlx4_dev *dev, int nent, | |||
864 | 872 | ||
865 | eq->dev = dev; | 873 | eq->dev = dev; |
866 | eq->nent = roundup_pow_of_two(max(nent, 2)); | 874 | eq->nent = roundup_pow_of_two(max(nent, 2)); |
867 | npages = PAGE_ALIGN(eq->nent * MLX4_EQ_ENTRY_SIZE) / PAGE_SIZE; | 875 | /* CX3 is capable of extending the CQE/EQE from 32 to 64 bytes */ |
876 | npages = PAGE_ALIGN(eq->nent * (MLX4_EQ_ENTRY_SIZE << dev->caps.eqe_factor)) / PAGE_SIZE; | ||
868 | 877 | ||
869 | eq->page_list = kmalloc(npages * sizeof *eq->page_list, | 878 | eq->page_list = kmalloc(npages * sizeof *eq->page_list, |
870 | GFP_KERNEL); | 879 | GFP_KERNEL); |
@@ -966,8 +975,9 @@ static void mlx4_free_eq(struct mlx4_dev *dev, | |||
966 | struct mlx4_priv *priv = mlx4_priv(dev); | 975 | struct mlx4_priv *priv = mlx4_priv(dev); |
967 | struct mlx4_cmd_mailbox *mailbox; | 976 | struct mlx4_cmd_mailbox *mailbox; |
968 | int err; | 977 | int err; |
969 | int npages = PAGE_ALIGN(MLX4_EQ_ENTRY_SIZE * eq->nent) / PAGE_SIZE; | ||
970 | int i; | 978 | int i; |
979 | /* CX3 is capable of extending the CQE/EQE from 32 to 64 bytes */ | ||
980 | int npages = PAGE_ALIGN((MLX4_EQ_ENTRY_SIZE << dev->caps.eqe_factor) * eq->nent) / PAGE_SIZE; | ||
971 | 981 | ||
972 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 982 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
973 | if (IS_ERR(mailbox)) | 983 | if (IS_ERR(mailbox)) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 4f30b99324cf..8b3d0512a46b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -110,6 +110,8 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags) | |||
110 | [42] = "Multicast VEP steering support", | 110 | [42] = "Multicast VEP steering support", |
111 | [48] = "Counters support", | 111 | [48] = "Counters support", |
112 | [59] = "Port management change event support", | 112 | [59] = "Port management change event support", |
113 | [61] = "64 byte EQE support", | ||
114 | [62] = "64 byte CQE support", | ||
113 | }; | 115 | }; |
114 | int i; | 116 | int i; |
115 | 117 | ||
@@ -235,7 +237,7 @@ int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
235 | field = dev->caps.num_ports; | 237 | field = dev->caps.num_ports; |
236 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); | 238 | MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); |
237 | 239 | ||
238 | size = 0; /* no PF behaviour is set for now */ | 240 | size = dev->caps.function_caps; /* set PF behaviours */ |
239 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); | 241 | MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); |
240 | 242 | ||
241 | field = 0; /* protected FMR support not available as yet */ | 243 | field = 0; /* protected FMR support not available as yet */ |
@@ -1237,6 +1239,24 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
1237 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS) | 1239 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS) |
1238 | *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 4); | 1240 | *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 4); |
1239 | 1241 | ||
1242 | /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ | ||
1243 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_EQE) { | ||
1244 | *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 29); | ||
1245 | dev->caps.eqe_size = 64; | ||
1246 | dev->caps.eqe_factor = 1; | ||
1247 | } else { | ||
1248 | dev->caps.eqe_size = 32; | ||
1249 | dev->caps.eqe_factor = 0; | ||
1250 | } | ||
1251 | |||
1252 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_CQE) { | ||
1253 | *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 30); | ||
1254 | dev->caps.cqe_size = 64; | ||
1255 | dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_64B_CQE; | ||
1256 | } else { | ||
1257 | dev->caps.cqe_size = 32; | ||
1258 | } | ||
1259 | |||
1240 | /* QPC/EEC/CQC/EQC/RDMARC attributes */ | 1260 | /* QPC/EEC/CQC/EQC/RDMARC attributes */ |
1241 | 1261 | ||
1242 | MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); | 1262 | MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); |
@@ -1318,7 +1338,9 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
1318 | { | 1338 | { |
1319 | struct mlx4_cmd_mailbox *mailbox; | 1339 | struct mlx4_cmd_mailbox *mailbox; |
1320 | __be32 *outbox; | 1340 | __be32 *outbox; |
1341 | u32 dword_field; | ||
1321 | int err; | 1342 | int err; |
1343 | u8 byte_field; | ||
1322 | 1344 | ||
1323 | #define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 | 1345 | #define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 |
1324 | 1346 | ||
@@ -1351,10 +1373,18 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
1351 | MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); | 1373 | MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); |
1352 | MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); | 1374 | MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); |
1353 | 1375 | ||
1376 | MLX4_GET(dword_field, outbox, INIT_HCA_FLAGS_OFFSET); | ||
1377 | if (dword_field & (1 << INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN)) { | ||
1378 | param->steering_mode = MLX4_STEERING_MODE_DEVICE_MANAGED; | ||
1379 | } else { | ||
1380 | MLX4_GET(byte_field, outbox, INIT_HCA_UC_STEERING_OFFSET); | ||
1381 | if (byte_field & 0x8) | ||
1382 | param->steering_mode = MLX4_STEERING_MODE_B0; | ||
1383 | else | ||
1384 | param->steering_mode = MLX4_STEERING_MODE_A0; | ||
1385 | } | ||
1354 | /* steering attributes */ | 1386 | /* steering attributes */ |
1355 | if (dev->caps.steering_mode == | 1387 | if (param->steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { |
1356 | MLX4_STEERING_MODE_DEVICE_MANAGED) { | ||
1357 | |||
1358 | MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET); | 1388 | MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET); |
1359 | MLX4_GET(param->log_mc_entry_sz, outbox, | 1389 | MLX4_GET(param->log_mc_entry_sz, outbox, |
1360 | INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); | 1390 | INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); |
@@ -1370,6 +1400,13 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
1370 | INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); | 1400 | INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); |
1371 | } | 1401 | } |
1372 | 1402 | ||
1403 | /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ | ||
1404 | MLX4_GET(byte_field, outbox, INIT_HCA_EQE_CQE_OFFSETS); | ||
1405 | if (byte_field & 0x20) /* 64-bytes eqe enabled */ | ||
1406 | param->dev_cap_enabled |= MLX4_DEV_CAP_64B_EQE_ENABLED; | ||
1407 | if (byte_field & 0x40) /* 64-bytes cqe enabled */ | ||
1408 | param->dev_cap_enabled |= MLX4_DEV_CAP_64B_CQE_ENABLED; | ||
1409 | |||
1373 | /* TPT attributes */ | 1410 | /* TPT attributes */ |
1374 | 1411 | ||
1375 | MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); | 1412 | MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 85abe9c11a22..dbf2f69cc59f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h | |||
@@ -172,6 +172,8 @@ struct mlx4_init_hca_param { | |||
172 | u8 log_uar_sz; | 172 | u8 log_uar_sz; |
173 | u8 uar_page_sz; /* log pg sz in 4k chunks */ | 173 | u8 uar_page_sz; /* log pg sz in 4k chunks */ |
174 | u8 fs_hash_enable_bits; | 174 | u8 fs_hash_enable_bits; |
175 | u8 steering_mode; /* for QUERY_HCA */ | ||
176 | u64 dev_cap_enabled; | ||
175 | }; | 177 | }; |
176 | 178 | ||
177 | struct mlx4_init_ib_param { | 179 | struct mlx4_init_ib_param { |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 2aa80afd98d2..a6542d75374c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -85,20 +85,26 @@ static int probe_vf; | |||
85 | module_param(probe_vf, int, 0644); | 85 | module_param(probe_vf, int, 0644); |
86 | MODULE_PARM_DESC(probe_vf, "number of vfs to probe by pf driver (num_vfs > 0)"); | 86 | MODULE_PARM_DESC(probe_vf, "number of vfs to probe by pf driver (num_vfs > 0)"); |
87 | 87 | ||
88 | int mlx4_log_num_mgm_entry_size = 10; | 88 | int mlx4_log_num_mgm_entry_size = MLX4_DEFAULT_MGM_LOG_ENTRY_SIZE; |
89 | module_param_named(log_num_mgm_entry_size, | 89 | module_param_named(log_num_mgm_entry_size, |
90 | mlx4_log_num_mgm_entry_size, int, 0444); | 90 | mlx4_log_num_mgm_entry_size, int, 0444); |
91 | MODULE_PARM_DESC(log_num_mgm_entry_size, "log mgm size, that defines the num" | 91 | MODULE_PARM_DESC(log_num_mgm_entry_size, "log mgm size, that defines the num" |
92 | " of qp per mcg, for example:" | 92 | " of qp per mcg, for example:" |
93 | " 10 gives 248.range: 9<=" | 93 | " 10 gives 248.range: 7 <=" |
94 | " log_num_mgm_entry_size <= 12." | 94 | " log_num_mgm_entry_size <= 12." |
95 | " Not in use with device managed" | 95 | " To activate device managed" |
96 | " flow steering"); | 96 | " flow steering when available, set to -1"); |
97 | |||
98 | static bool enable_64b_cqe_eqe; | ||
99 | module_param(enable_64b_cqe_eqe, bool, 0444); | ||
100 | MODULE_PARM_DESC(enable_64b_cqe_eqe, | ||
101 | "Enable 64 byte CQEs/EQEs when the the FW supports this"); | ||
97 | 102 | ||
98 | #define HCA_GLOBAL_CAP_MASK 0 | 103 | #define HCA_GLOBAL_CAP_MASK 0 |
99 | #define PF_CONTEXT_BEHAVIOUR_MASK 0 | ||
100 | 104 | ||
101 | static char mlx4_version[] __devinitdata = | 105 | #define PF_CONTEXT_BEHAVIOUR_MASK MLX4_FUNC_CAP_64B_EQE_CQE |
106 | |||
107 | static char mlx4_version[] = | ||
102 | DRV_NAME ": Mellanox ConnectX core driver v" | 108 | DRV_NAME ": Mellanox ConnectX core driver v" |
103 | DRV_VERSION " (" DRV_RELDATE ")\n"; | 109 | DRV_VERSION " (" DRV_RELDATE ")\n"; |
104 | 110 | ||
@@ -275,28 +281,6 @@ 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; | 281 | dev->caps.max_gso_sz = dev_cap->max_gso_sz; |
276 | dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz; | 282 | dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz; |
277 | 283 | ||
278 | if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_FS_EN) { | ||
279 | dev->caps.steering_mode = MLX4_STEERING_MODE_DEVICE_MANAGED; | ||
280 | dev->caps.num_qp_per_mgm = dev_cap->fs_max_num_qp_per_entry; | ||
281 | dev->caps.fs_log_max_ucast_qp_range_size = | ||
282 | dev_cap->fs_log_max_ucast_qp_range_size; | ||
283 | } else { | ||
284 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && | ||
285 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) { | ||
286 | dev->caps.steering_mode = MLX4_STEERING_MODE_B0; | ||
287 | } else { | ||
288 | dev->caps.steering_mode = MLX4_STEERING_MODE_A0; | ||
289 | |||
290 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER || | ||
291 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) | ||
292 | mlx4_warn(dev, "Must have UC_STEER and MC_STEER flags " | ||
293 | "set to use B0 steering. Falling back to A0 steering mode.\n"); | ||
294 | } | ||
295 | dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); | ||
296 | } | ||
297 | mlx4_dbg(dev, "Steering mode is: %s\n", | ||
298 | mlx4_steering_mode_str(dev->caps.steering_mode)); | ||
299 | |||
300 | /* Sense port always allowed on supported devices for ConnectX-1 and -2 */ | 284 | /* Sense port always allowed on supported devices for ConnectX-1 and -2 */ |
301 | if (mlx4_priv(dev)->pci_dev_data & MLX4_PCI_DEV_FORCE_SENSE_PORT) | 285 | if (mlx4_priv(dev)->pci_dev_data & MLX4_PCI_DEV_FORCE_SENSE_PORT) |
302 | dev->caps.flags |= MLX4_DEV_CAP_FLAG_SENSE_SUPPORT; | 286 | dev->caps.flags |= MLX4_DEV_CAP_FLAG_SENSE_SUPPORT; |
@@ -386,6 +370,21 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
386 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH]; | 370 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH]; |
387 | 371 | ||
388 | dev->caps.sqp_demux = (mlx4_is_master(dev)) ? MLX4_MAX_NUM_SLAVES : 0; | 372 | dev->caps.sqp_demux = (mlx4_is_master(dev)) ? MLX4_MAX_NUM_SLAVES : 0; |
373 | |||
374 | if (!enable_64b_cqe_eqe) { | ||
375 | if (dev_cap->flags & | ||
376 | (MLX4_DEV_CAP_FLAG_64B_CQE | MLX4_DEV_CAP_FLAG_64B_EQE)) { | ||
377 | mlx4_warn(dev, "64B EQEs/CQEs supported by the device but not enabled\n"); | ||
378 | dev->caps.flags &= ~MLX4_DEV_CAP_FLAG_64B_CQE; | ||
379 | dev->caps.flags &= ~MLX4_DEV_CAP_FLAG_64B_EQE; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | if ((dev_cap->flags & | ||
384 | (MLX4_DEV_CAP_FLAG_64B_CQE | MLX4_DEV_CAP_FLAG_64B_EQE)) && | ||
385 | mlx4_is_master(dev)) | ||
386 | dev->caps.function_caps |= MLX4_FUNC_CAP_64B_EQE_CQE; | ||
387 | |||
389 | return 0; | 388 | return 0; |
390 | } | 389 | } |
391 | /*The function checks if there are live vf, return the num of them*/ | 390 | /*The function checks if there are live vf, return the num of them*/ |
@@ -472,6 +471,23 @@ int mlx4_is_slave_active(struct mlx4_dev *dev, int slave) | |||
472 | } | 471 | } |
473 | EXPORT_SYMBOL(mlx4_is_slave_active); | 472 | EXPORT_SYMBOL(mlx4_is_slave_active); |
474 | 473 | ||
474 | static void slave_adjust_steering_mode(struct mlx4_dev *dev, | ||
475 | struct mlx4_dev_cap *dev_cap, | ||
476 | struct mlx4_init_hca_param *hca_param) | ||
477 | { | ||
478 | dev->caps.steering_mode = hca_param->steering_mode; | ||
479 | if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { | ||
480 | dev->caps.num_qp_per_mgm = dev_cap->fs_max_num_qp_per_entry; | ||
481 | dev->caps.fs_log_max_ucast_qp_range_size = | ||
482 | dev_cap->fs_log_max_ucast_qp_range_size; | ||
483 | } else | ||
484 | dev->caps.num_qp_per_mgm = | ||
485 | 4 * ((1 << hca_param->log_mc_entry_sz)/16 - 2); | ||
486 | |||
487 | mlx4_dbg(dev, "Steering mode is: %s\n", | ||
488 | mlx4_steering_mode_str(dev->caps.steering_mode)); | ||
489 | } | ||
490 | |||
475 | static int mlx4_slave_cap(struct mlx4_dev *dev) | 491 | static int mlx4_slave_cap(struct mlx4_dev *dev) |
476 | { | 492 | { |
477 | int err; | 493 | int err; |
@@ -599,6 +615,23 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
599 | goto err_mem; | 615 | goto err_mem; |
600 | } | 616 | } |
601 | 617 | ||
618 | if (hca_param.dev_cap_enabled & MLX4_DEV_CAP_64B_EQE_ENABLED) { | ||
619 | dev->caps.eqe_size = 64; | ||
620 | dev->caps.eqe_factor = 1; | ||
621 | } else { | ||
622 | dev->caps.eqe_size = 32; | ||
623 | dev->caps.eqe_factor = 0; | ||
624 | } | ||
625 | |||
626 | if (hca_param.dev_cap_enabled & MLX4_DEV_CAP_64B_CQE_ENABLED) { | ||
627 | dev->caps.cqe_size = 64; | ||
628 | dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_64B_CQE; | ||
629 | } else { | ||
630 | dev->caps.cqe_size = 32; | ||
631 | } | ||
632 | |||
633 | slave_adjust_steering_mode(dev, &dev_cap, &hca_param); | ||
634 | |||
602 | return 0; | 635 | return 0; |
603 | 636 | ||
604 | err_mem: | 637 | err_mem: |
@@ -1285,6 +1318,59 @@ static void mlx4_parav_master_pf_caps(struct mlx4_dev *dev) | |||
1285 | } | 1318 | } |
1286 | } | 1319 | } |
1287 | 1320 | ||
1321 | static int choose_log_fs_mgm_entry_size(int qp_per_entry) | ||
1322 | { | ||
1323 | int i = MLX4_MIN_MGM_LOG_ENTRY_SIZE; | ||
1324 | |||
1325 | for (i = MLX4_MIN_MGM_LOG_ENTRY_SIZE; i <= MLX4_MAX_MGM_LOG_ENTRY_SIZE; | ||
1326 | i++) { | ||
1327 | if (qp_per_entry <= 4 * ((1 << i) / 16 - 2)) | ||
1328 | break; | ||
1329 | } | ||
1330 | |||
1331 | return (i <= MLX4_MAX_MGM_LOG_ENTRY_SIZE) ? i : -1; | ||
1332 | } | ||
1333 | |||
1334 | static void choose_steering_mode(struct mlx4_dev *dev, | ||
1335 | struct mlx4_dev_cap *dev_cap) | ||
1336 | { | ||
1337 | if (mlx4_log_num_mgm_entry_size == -1 && | ||
1338 | dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_FS_EN && | ||
1339 | (!mlx4_is_mfunc(dev) || | ||
1340 | (dev_cap->fs_max_num_qp_per_entry >= (num_vfs + 1))) && | ||
1341 | choose_log_fs_mgm_entry_size(dev_cap->fs_max_num_qp_per_entry) >= | ||
1342 | MLX4_MIN_MGM_LOG_ENTRY_SIZE) { | ||
1343 | dev->oper_log_mgm_entry_size = | ||
1344 | choose_log_fs_mgm_entry_size(dev_cap->fs_max_num_qp_per_entry); | ||
1345 | dev->caps.steering_mode = MLX4_STEERING_MODE_DEVICE_MANAGED; | ||
1346 | dev->caps.num_qp_per_mgm = dev_cap->fs_max_num_qp_per_entry; | ||
1347 | dev->caps.fs_log_max_ucast_qp_range_size = | ||
1348 | dev_cap->fs_log_max_ucast_qp_range_size; | ||
1349 | } else { | ||
1350 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && | ||
1351 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) | ||
1352 | dev->caps.steering_mode = MLX4_STEERING_MODE_B0; | ||
1353 | else { | ||
1354 | dev->caps.steering_mode = MLX4_STEERING_MODE_A0; | ||
1355 | |||
1356 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER || | ||
1357 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) | ||
1358 | mlx4_warn(dev, "Must have both UC_STEER and MC_STEER flags " | ||
1359 | "set to use B0 steering. Falling back to A0 steering mode.\n"); | ||
1360 | } | ||
1361 | dev->oper_log_mgm_entry_size = | ||
1362 | mlx4_log_num_mgm_entry_size > 0 ? | ||
1363 | mlx4_log_num_mgm_entry_size : | ||
1364 | MLX4_DEFAULT_MGM_LOG_ENTRY_SIZE; | ||
1365 | dev->caps.num_qp_per_mgm = mlx4_get_qp_per_mgm(dev); | ||
1366 | } | ||
1367 | mlx4_dbg(dev, "Steering mode is: %s, oper_log_mgm_entry_size = %d, " | ||
1368 | "modparam log_num_mgm_entry_size = %d\n", | ||
1369 | mlx4_steering_mode_str(dev->caps.steering_mode), | ||
1370 | dev->oper_log_mgm_entry_size, | ||
1371 | mlx4_log_num_mgm_entry_size); | ||
1372 | } | ||
1373 | |||
1288 | static int mlx4_init_hca(struct mlx4_dev *dev) | 1374 | static int mlx4_init_hca(struct mlx4_dev *dev) |
1289 | { | 1375 | { |
1290 | struct mlx4_priv *priv = mlx4_priv(dev); | 1376 | struct mlx4_priv *priv = mlx4_priv(dev); |
@@ -1324,6 +1410,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1324 | goto err_stop_fw; | 1410 | goto err_stop_fw; |
1325 | } | 1411 | } |
1326 | 1412 | ||
1413 | choose_steering_mode(dev, &dev_cap); | ||
1414 | |||
1327 | if (mlx4_is_master(dev)) | 1415 | if (mlx4_is_master(dev)) |
1328 | mlx4_parav_master_pf_caps(dev); | 1416 | mlx4_parav_master_pf_caps(dev); |
1329 | 1417 | ||
@@ -1702,15 +1790,8 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) | |||
1702 | int i; | 1790 | int i; |
1703 | 1791 | ||
1704 | if (msi_x) { | 1792 | if (msi_x) { |
1705 | /* In multifunction mode each function gets 2 msi-X vectors | 1793 | nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs, |
1706 | * one for data path completions anf the other for asynch events | 1794 | nreq); |
1707 | * or command completions */ | ||
1708 | if (mlx4_is_mfunc(dev)) { | ||
1709 | nreq = 2; | ||
1710 | } else { | ||
1711 | nreq = min_t(int, dev->caps.num_eqs - | ||
1712 | dev->caps.reserved_eqs, nreq); | ||
1713 | } | ||
1714 | 1795 | ||
1715 | entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); | 1796 | entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL); |
1716 | if (!entries) | 1797 | if (!entries) |
@@ -2224,8 +2305,7 @@ err_disable_pdev: | |||
2224 | return err; | 2305 | return err; |
2225 | } | 2306 | } |
2226 | 2307 | ||
2227 | static int __devinit mlx4_init_one(struct pci_dev *pdev, | 2308 | static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
2228 | const struct pci_device_id *id) | ||
2229 | { | 2309 | { |
2230 | printk_once(KERN_INFO "%s", mlx4_version); | 2310 | printk_once(KERN_INFO "%s", mlx4_version); |
2231 | 2311 | ||
@@ -2391,7 +2471,7 @@ static struct pci_driver mlx4_driver = { | |||
2391 | .name = DRV_NAME, | 2471 | .name = DRV_NAME, |
2392 | .id_table = mlx4_pci_table, | 2472 | .id_table = mlx4_pci_table, |
2393 | .probe = mlx4_init_one, | 2473 | .probe = mlx4_init_one, |
2394 | .remove = __devexit_p(mlx4_remove_one), | 2474 | .remove = mlx4_remove_one, |
2395 | .err_handler = &mlx4_err_handler, | 2475 | .err_handler = &mlx4_err_handler, |
2396 | }; | 2476 | }; |
2397 | 2477 | ||
@@ -2417,6 +2497,17 @@ static int __init mlx4_verify_params(void) | |||
2417 | port_type_array[0] = true; | 2497 | port_type_array[0] = true; |
2418 | } | 2498 | } |
2419 | 2499 | ||
2500 | if (mlx4_log_num_mgm_entry_size != -1 && | ||
2501 | (mlx4_log_num_mgm_entry_size < MLX4_MIN_MGM_LOG_ENTRY_SIZE || | ||
2502 | mlx4_log_num_mgm_entry_size > MLX4_MAX_MGM_LOG_ENTRY_SIZE)) { | ||
2503 | pr_warning("mlx4_core: mlx4_log_num_mgm_entry_size (%d) not " | ||
2504 | "in legal range (-1 or %d..%d)\n", | ||
2505 | mlx4_log_num_mgm_entry_size, | ||
2506 | MLX4_MIN_MGM_LOG_ENTRY_SIZE, | ||
2507 | MLX4_MAX_MGM_LOG_ENTRY_SIZE); | ||
2508 | return -1; | ||
2509 | } | ||
2510 | |||
2420 | return 0; | 2511 | return 0; |
2421 | } | 2512 | } |
2422 | 2513 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index e151c21baf2b..1ee4db3c6400 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
@@ -54,12 +54,7 @@ struct mlx4_mgm { | |||
54 | 54 | ||
55 | int mlx4_get_mgm_entry_size(struct mlx4_dev *dev) | 55 | int mlx4_get_mgm_entry_size(struct mlx4_dev *dev) |
56 | { | 56 | { |
57 | if (dev->caps.steering_mode == | 57 | return 1 << dev->oper_log_mgm_entry_size; |
58 | MLX4_STEERING_MODE_DEVICE_MANAGED) | ||
59 | return 1 << MLX4_FS_MGM_LOG_ENTRY_SIZE; | ||
60 | else | ||
61 | return min((1 << mlx4_log_num_mgm_entry_size), | ||
62 | MLX4_MAX_MGM_ENTRY_SIZE); | ||
63 | } | 58 | } |
64 | 59 | ||
65 | int mlx4_get_qp_per_mgm(struct mlx4_dev *dev) | 60 | int mlx4_get_qp_per_mgm(struct mlx4_dev *dev) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 1cf42036d7bb..116c5c29d2d1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -94,8 +94,10 @@ enum { | |||
94 | }; | 94 | }; |
95 | 95 | ||
96 | enum { | 96 | enum { |
97 | MLX4_MAX_MGM_ENTRY_SIZE = 0x1000, | 97 | MLX4_DEFAULT_MGM_LOG_ENTRY_SIZE = 10, |
98 | MLX4_MAX_QP_PER_MGM = 4 * (MLX4_MAX_MGM_ENTRY_SIZE / 16 - 2), | 98 | MLX4_MIN_MGM_LOG_ENTRY_SIZE = 7, |
99 | MLX4_MAX_MGM_LOG_ENTRY_SIZE = 12, | ||
100 | MLX4_MAX_QP_PER_MGM = 4 * ((1 << MLX4_MAX_MGM_LOG_ENTRY_SIZE) / 16 - 2), | ||
99 | MLX4_MTT_ENTRY_PER_SEG = 8, | 101 | MLX4_MTT_ENTRY_PER_SEG = 8, |
100 | }; | 102 | }; |
101 | 103 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 9d27e42264e2..8d54412ada63 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -67,7 +67,8 @@ | |||
67 | 67 | ||
68 | #define MLX4_EN_PAGE_SHIFT 12 | 68 | #define MLX4_EN_PAGE_SHIFT 12 |
69 | #define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT) | 69 | #define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT) |
70 | #define MAX_RX_RINGS 16 | 70 | #define DEF_RX_RINGS 16 |
71 | #define MAX_RX_RINGS 128 | ||
71 | #define MIN_RX_RINGS 4 | 72 | #define MIN_RX_RINGS 4 |
72 | #define TXBB_SIZE 64 | 73 | #define TXBB_SIZE 64 |
73 | #define HEADROOM (2048 / TXBB_SIZE + 1) | 74 | #define HEADROOM (2048 / TXBB_SIZE + 1) |
@@ -95,8 +96,6 @@ | |||
95 | #define MLX4_EN_ALLOC_SIZE PAGE_ALIGN(16384) | 96 | #define MLX4_EN_ALLOC_SIZE PAGE_ALIGN(16384) |
96 | #define MLX4_EN_ALLOC_ORDER get_order(MLX4_EN_ALLOC_SIZE) | 97 | #define MLX4_EN_ALLOC_ORDER get_order(MLX4_EN_ALLOC_SIZE) |
97 | 98 | ||
98 | #define MLX4_EN_MAX_LRO_DESCRIPTORS 32 | ||
99 | |||
100 | /* Receive fragment sizes; we use at most 4 fragments (for 9600 byte MTU | 99 | /* Receive fragment sizes; we use at most 4 fragments (for 9600 byte MTU |
101 | * and 4K allocations) */ | 100 | * and 4K allocations) */ |
102 | enum { | 101 | enum { |
@@ -120,13 +119,15 @@ enum { | |||
120 | #define MLX4_EN_NUM_UP 8 | 119 | #define MLX4_EN_NUM_UP 8 |
121 | #define MLX4_EN_DEF_TX_RING_SIZE 512 | 120 | #define MLX4_EN_DEF_TX_RING_SIZE 512 |
122 | #define MLX4_EN_DEF_RX_RING_SIZE 1024 | 121 | #define MLX4_EN_DEF_RX_RING_SIZE 1024 |
122 | #define MAX_TX_RINGS (MLX4_EN_MAX_TX_RING_P_UP * \ | ||
123 | MLX4_EN_NUM_UP) | ||
123 | 124 | ||
124 | /* Target number of packets to coalesce with interrupt moderation */ | 125 | /* Target number of packets to coalesce with interrupt moderation */ |
125 | #define MLX4_EN_RX_COAL_TARGET 44 | 126 | #define MLX4_EN_RX_COAL_TARGET 44 |
126 | #define MLX4_EN_RX_COAL_TIME 0x10 | 127 | #define MLX4_EN_RX_COAL_TIME 0x10 |
127 | 128 | ||
128 | #define MLX4_EN_TX_COAL_PKTS 16 | 129 | #define MLX4_EN_TX_COAL_PKTS 16 |
129 | #define MLX4_EN_TX_COAL_TIME 0x80 | 130 | #define MLX4_EN_TX_COAL_TIME 0x10 |
130 | 131 | ||
131 | #define MLX4_EN_RX_RATE_LOW 400000 | 132 | #define MLX4_EN_RX_RATE_LOW 400000 |
132 | #define MLX4_EN_RX_COAL_TIME_LOW 0 | 133 | #define MLX4_EN_RX_COAL_TIME_LOW 0 |
@@ -290,21 +291,6 @@ struct mlx4_en_rx_ring { | |||
290 | unsigned long csum_none; | 291 | unsigned long csum_none; |
291 | }; | 292 | }; |
292 | 293 | ||
293 | |||
294 | static inline int mlx4_en_can_lro(__be16 status) | ||
295 | { | ||
296 | return (status & cpu_to_be16(MLX4_CQE_STATUS_IPV4 | | ||
297 | MLX4_CQE_STATUS_IPV4F | | ||
298 | MLX4_CQE_STATUS_IPV6 | | ||
299 | MLX4_CQE_STATUS_IPV4OPT | | ||
300 | MLX4_CQE_STATUS_TCP | | ||
301 | MLX4_CQE_STATUS_UDP | | ||
302 | MLX4_CQE_STATUS_IPOK)) == | ||
303 | cpu_to_be16(MLX4_CQE_STATUS_IPV4 | | ||
304 | MLX4_CQE_STATUS_IPOK | | ||
305 | MLX4_CQE_STATUS_TCP); | ||
306 | } | ||
307 | |||
308 | struct mlx4_en_cq { | 294 | struct mlx4_en_cq { |
309 | struct mlx4_cq mcq; | 295 | struct mlx4_cq mcq; |
310 | struct mlx4_hwq_resources wqres; | 296 | struct mlx4_hwq_resources wqres; |
@@ -487,12 +473,14 @@ struct mlx4_en_priv { | |||
487 | int mac_index; | 473 | int mac_index; |
488 | unsigned max_mtu; | 474 | unsigned max_mtu; |
489 | int base_qpn; | 475 | int base_qpn; |
476 | int cqe_factor; | ||
490 | 477 | ||
491 | struct mlx4_en_rss_map rss_map; | 478 | struct mlx4_en_rss_map rss_map; |
492 | __be32 ctrl_flags; | 479 | __be32 ctrl_flags; |
493 | u32 flags; | 480 | u32 flags; |
494 | #define MLX4_EN_FLAG_PROMISC 0x1 | 481 | #define MLX4_EN_FLAG_PROMISC 0x1 |
495 | #define MLX4_EN_FLAG_MC_PROMISC 0x2 | 482 | #define MLX4_EN_FLAG_MC_PROMISC 0x2 |
483 | u8 num_tx_rings_p_up; | ||
496 | u32 tx_ring_num; | 484 | u32 tx_ring_num; |
497 | u32 rx_ring_num; | 485 | u32 rx_ring_num; |
498 | u32 rx_skb_size; | 486 | u32 rx_skb_size; |
@@ -613,6 +601,8 @@ int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port); | |||
613 | extern const struct dcbnl_rtnl_ops mlx4_en_dcbnl_ops; | 601 | extern const struct dcbnl_rtnl_ops mlx4_en_dcbnl_ops; |
614 | #endif | 602 | #endif |
615 | 603 | ||
604 | int mlx4_en_setup_tc(struct net_device *dev, u8 up); | ||
605 | |||
616 | #ifdef CONFIG_RFS_ACCEL | 606 | #ifdef CONFIG_RFS_ACCEL |
617 | void mlx4_en_cleanup_filters(struct mlx4_en_priv *priv, | 607 | void mlx4_en_cleanup_filters(struct mlx4_en_priv *priv, |
618 | struct mlx4_en_rx_ring *rx_ring); | 608 | struct mlx4_en_rx_ring *rx_ring); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index b05705f50f0f..561ed2a22a17 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -3071,6 +3071,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
3071 | struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; | 3071 | struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; |
3072 | struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC]; | 3072 | struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC]; |
3073 | int err; | 3073 | int err; |
3074 | int qpn; | ||
3074 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | 3075 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; |
3075 | struct _rule_hw *rule_header; | 3076 | struct _rule_hw *rule_header; |
3076 | int header_id; | 3077 | int header_id; |
@@ -3080,13 +3081,21 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
3080 | return -EOPNOTSUPP; | 3081 | return -EOPNOTSUPP; |
3081 | 3082 | ||
3082 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | 3083 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; |
3084 | qpn = be32_to_cpu(ctrl->qpn) & 0xffffff; | ||
3085 | err = get_res(dev, slave, qpn, RES_QP, NULL); | ||
3086 | if (err) { | ||
3087 | pr_err("Steering rule with qpn 0x%x rejected.\n", qpn); | ||
3088 | return err; | ||
3089 | } | ||
3083 | rule_header = (struct _rule_hw *)(ctrl + 1); | 3090 | rule_header = (struct _rule_hw *)(ctrl + 1); |
3084 | header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); | 3091 | header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); |
3085 | 3092 | ||
3086 | switch (header_id) { | 3093 | switch (header_id) { |
3087 | case MLX4_NET_TRANS_RULE_ID_ETH: | 3094 | case MLX4_NET_TRANS_RULE_ID_ETH: |
3088 | if (validate_eth_header_mac(slave, rule_header, rlist)) | 3095 | if (validate_eth_header_mac(slave, rule_header, rlist)) { |
3089 | return -EINVAL; | 3096 | err = -EINVAL; |
3097 | goto err_put; | ||
3098 | } | ||
3090 | break; | 3099 | break; |
3091 | case MLX4_NET_TRANS_RULE_ID_IB: | 3100 | case MLX4_NET_TRANS_RULE_ID_IB: |
3092 | break; | 3101 | break; |
@@ -3094,14 +3103,17 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
3094 | case MLX4_NET_TRANS_RULE_ID_TCP: | 3103 | case MLX4_NET_TRANS_RULE_ID_TCP: |
3095 | case MLX4_NET_TRANS_RULE_ID_UDP: | 3104 | case MLX4_NET_TRANS_RULE_ID_UDP: |
3096 | pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); | 3105 | pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); |
3097 | if (add_eth_header(dev, slave, inbox, rlist, header_id)) | 3106 | if (add_eth_header(dev, slave, inbox, rlist, header_id)) { |
3098 | return -EINVAL; | 3107 | err = -EINVAL; |
3108 | goto err_put; | ||
3109 | } | ||
3099 | vhcr->in_modifier += | 3110 | vhcr->in_modifier += |
3100 | sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; | 3111 | sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; |
3101 | break; | 3112 | break; |
3102 | default: | 3113 | default: |
3103 | pr_err("Corrupted mailbox.\n"); | 3114 | pr_err("Corrupted mailbox.\n"); |
3104 | return -EINVAL; | 3115 | err = -EINVAL; |
3116 | goto err_put; | ||
3105 | } | 3117 | } |
3106 | 3118 | ||
3107 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, | 3119 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, |
@@ -3109,16 +3121,18 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
3109 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, | 3121 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, |
3110 | MLX4_CMD_NATIVE); | 3122 | MLX4_CMD_NATIVE); |
3111 | if (err) | 3123 | if (err) |
3112 | return err; | 3124 | goto err_put; |
3113 | 3125 | ||
3114 | err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0); | 3126 | err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0); |
3115 | if (err) { | 3127 | if (err) { |
3116 | mlx4_err(dev, "Fail to add flow steering resources.\n "); | 3128 | mlx4_err(dev, "Fail to add flow steering resources.\n "); |
3117 | /* detach rule*/ | 3129 | /* detach rule*/ |
3118 | mlx4_cmd(dev, vhcr->out_param, 0, 0, | 3130 | mlx4_cmd(dev, vhcr->out_param, 0, 0, |
3119 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, | 3131 | MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, |
3120 | MLX4_CMD_NATIVE); | 3132 | MLX4_CMD_NATIVE); |
3121 | } | 3133 | } |
3134 | err_put: | ||
3135 | put_res(dev, slave, qpn, RES_QP); | ||
3122 | return err; | 3136 | return err; |
3123 | } | 3137 | } |
3124 | 3138 | ||