diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 48 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 132 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/qp.c | 4 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 17 |
7 files changed, 191 insertions, 19 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 568e1f41fdd4..6ff214de1111 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -2594,7 +2594,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
2594 | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; | 2594 | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; |
2595 | 2595 | ||
2596 | if (mdev->dev->caps.steering_mode == | 2596 | if (mdev->dev->caps.steering_mode == |
2597 | MLX4_STEERING_MODE_DEVICE_MANAGED) | 2597 | MLX4_STEERING_MODE_DEVICE_MANAGED && |
2598 | mdev->dev->caps.dmfs_high_steer_mode != MLX4_STEERING_DMFS_A0_STATIC) | ||
2598 | dev->hw_features |= NETIF_F_NTUPLE; | 2599 | dev->hw_features |= NETIF_F_NTUPLE; |
2599 | 2600 | ||
2600 | if (mdev->dev->caps.steering_mode != MLX4_STEERING_MODE_A0) | 2601 | if (mdev->dev->caps.steering_mode != MLX4_STEERING_MODE_A0) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 073b3d1c8b91..ef3b95bac2ad 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -144,7 +144,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) | |||
144 | [15] = "Ethernet Backplane autoneg support", | 144 | [15] = "Ethernet Backplane autoneg support", |
145 | [16] = "CONFIG DEV support", | 145 | [16] = "CONFIG DEV support", |
146 | [17] = "Asymmetric EQs support", | 146 | [17] = "Asymmetric EQs support", |
147 | [18] = "More than 80 VFs support" | 147 | [18] = "More than 80 VFs support", |
148 | [19] = "Performance optimized for limited rule configuration flow steering support" | ||
148 | }; | 149 | }; |
149 | int i; | 150 | int i; |
150 | 151 | ||
@@ -680,6 +681,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
680 | #define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d | 681 | #define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d |
681 | #define QUERY_DEV_CAP_VXLAN 0x9e | 682 | #define QUERY_DEV_CAP_VXLAN 0x9e |
682 | #define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 | 683 | #define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 |
684 | #define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8 | ||
685 | #define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac | ||
683 | 686 | ||
684 | dev_cap->flags2 = 0; | 687 | dev_cap->flags2 = 0; |
685 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 688 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
@@ -876,6 +879,13 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
876 | if (field32 & (1 << 0)) | 879 | if (field32 & (1 << 0)) |
877 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_MAD_DEMUX; | 880 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_MAD_DEMUX; |
878 | 881 | ||
882 | MLX4_GET(dev_cap->dmfs_high_rate_qpn_base, outbox, | ||
883 | QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET); | ||
884 | dev_cap->dmfs_high_rate_qpn_base &= MGM_QPN_MASK; | ||
885 | MLX4_GET(dev_cap->dmfs_high_rate_qpn_range, outbox, | ||
886 | QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET); | ||
887 | dev_cap->dmfs_high_rate_qpn_range &= MGM_QPN_MASK; | ||
888 | |||
879 | MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); | 889 | MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); |
880 | if (field32 & (1 << 16)) | 890 | if (field32 & (1 << 16)) |
881 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; | 891 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; |
@@ -935,6 +945,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
935 | mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz); | 945 | mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz); |
936 | mlx4_dbg(dev, "Max counters: %d\n", dev_cap->max_counters); | 946 | mlx4_dbg(dev, "Max counters: %d\n", dev_cap->max_counters); |
937 | mlx4_dbg(dev, "Max RSS Table size: %d\n", dev_cap->max_rss_tbl_sz); | 947 | mlx4_dbg(dev, "Max RSS Table size: %d\n", dev_cap->max_rss_tbl_sz); |
948 | mlx4_dbg(dev, "DMFS high rate steer QPn base: %d\n", | ||
949 | dev_cap->dmfs_high_rate_qpn_base); | ||
950 | mlx4_dbg(dev, "DMFS high rate steer QPn range: %d\n", | ||
951 | dev_cap->dmfs_high_rate_qpn_range); | ||
938 | 952 | ||
939 | dump_dev_cap_flags(dev, dev_cap->flags); | 953 | dump_dev_cap_flags(dev, dev_cap->flags); |
940 | dump_dev_cap_flags2(dev, dev_cap->flags2); | 954 | dump_dev_cap_flags2(dev, dev_cap->flags2); |
@@ -996,6 +1010,7 @@ int mlx4_QUERY_PORT(struct mlx4_dev *dev, int port, struct mlx4_port_cap *port_c | |||
996 | port_cap->supported_port_types = field & 3; | 1010 | port_cap->supported_port_types = field & 3; |
997 | port_cap->suggested_type = (field >> 3) & 1; | 1011 | port_cap->suggested_type = (field >> 3) & 1; |
998 | port_cap->default_sense = (field >> 4) & 1; | 1012 | port_cap->default_sense = (field >> 4) & 1; |
1013 | port_cap->dmfs_optimized_state = (field >> 5) & 1; | ||
999 | MLX4_GET(field, outbox, QUERY_PORT_MTU_OFFSET); | 1014 | MLX4_GET(field, outbox, QUERY_PORT_MTU_OFFSET); |
1000 | port_cap->ib_mtu = field & 0xf; | 1015 | port_cap->ib_mtu = field & 0xf; |
1001 | MLX4_GET(field, outbox, QUERY_PORT_WIDTH_OFFSET); | 1016 | MLX4_GET(field, outbox, QUERY_PORT_WIDTH_OFFSET); |
@@ -1530,6 +1545,12 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
1530 | struct mlx4_cmd_mailbox *mailbox; | 1545 | struct mlx4_cmd_mailbox *mailbox; |
1531 | __be32 *inbox; | 1546 | __be32 *inbox; |
1532 | int err; | 1547 | int err; |
1548 | static const u8 a0_dmfs_hw_steering[] = { | ||
1549 | [MLX4_STEERING_DMFS_A0_DEFAULT] = 0, | ||
1550 | [MLX4_STEERING_DMFS_A0_DYNAMIC] = 1, | ||
1551 | [MLX4_STEERING_DMFS_A0_STATIC] = 2, | ||
1552 | [MLX4_STEERING_DMFS_A0_DISABLE] = 3 | ||
1553 | }; | ||
1533 | 1554 | ||
1534 | #define INIT_HCA_IN_SIZE 0x200 | 1555 | #define INIT_HCA_IN_SIZE 0x200 |
1535 | #define INIT_HCA_VERSION_OFFSET 0x000 | 1556 | #define INIT_HCA_VERSION_OFFSET 0x000 |
@@ -1563,6 +1584,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
1563 | #define INIT_HCA_FS_PARAM_OFFSET 0x1d0 | 1584 | #define INIT_HCA_FS_PARAM_OFFSET 0x1d0 |
1564 | #define INIT_HCA_FS_BASE_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x00) | 1585 | #define INIT_HCA_FS_BASE_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x00) |
1565 | #define INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x12) | 1586 | #define INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x12) |
1587 | #define INIT_HCA_FS_A0_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x18) | ||
1566 | #define INIT_HCA_FS_LOG_TABLE_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x1b) | 1588 | #define INIT_HCA_FS_LOG_TABLE_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x1b) |
1567 | #define INIT_HCA_FS_ETH_BITS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x21) | 1589 | #define INIT_HCA_FS_ETH_BITS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x21) |
1568 | #define INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x22) | 1590 | #define INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x22) |
@@ -1673,8 +1695,11 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
1673 | /* Enable Ethernet flow steering | 1695 | /* Enable Ethernet flow steering |
1674 | * with udp unicast and tcp unicast | 1696 | * with udp unicast and tcp unicast |
1675 | */ | 1697 | */ |
1676 | MLX4_PUT(inbox, (u8) (MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN), | 1698 | if (dev->caps.dmfs_high_steer_mode != |
1677 | INIT_HCA_FS_ETH_BITS_OFFSET); | 1699 | MLX4_STEERING_DMFS_A0_STATIC) |
1700 | MLX4_PUT(inbox, | ||
1701 | (u8)(MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN), | ||
1702 | INIT_HCA_FS_ETH_BITS_OFFSET); | ||
1678 | MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, | 1703 | MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, |
1679 | INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET); | 1704 | INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET); |
1680 | /* Enable IPoIB flow steering | 1705 | /* Enable IPoIB flow steering |
@@ -1684,6 +1709,13 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
1684 | INIT_HCA_FS_IB_BITS_OFFSET); | 1709 | INIT_HCA_FS_IB_BITS_OFFSET); |
1685 | MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, | 1710 | MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, |
1686 | INIT_HCA_FS_IB_NUM_ADDRS_OFFSET); | 1711 | INIT_HCA_FS_IB_NUM_ADDRS_OFFSET); |
1712 | |||
1713 | if (dev->caps.dmfs_high_steer_mode != | ||
1714 | MLX4_STEERING_DMFS_A0_NOT_SUPPORTED) | ||
1715 | MLX4_PUT(inbox, | ||
1716 | ((u8)(a0_dmfs_hw_steering[dev->caps.dmfs_high_steer_mode] | ||
1717 | << 6)), | ||
1718 | INIT_HCA_FS_A0_OFFSET); | ||
1687 | } else { | 1719 | } else { |
1688 | MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); | 1720 | MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); |
1689 | MLX4_PUT(inbox, param->log_mc_entry_sz, | 1721 | MLX4_PUT(inbox, param->log_mc_entry_sz, |
@@ -1734,6 +1766,12 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
1734 | u32 dword_field; | 1766 | u32 dword_field; |
1735 | int err; | 1767 | int err; |
1736 | u8 byte_field; | 1768 | u8 byte_field; |
1769 | static const u8 a0_dmfs_query_hw_steering[] = { | ||
1770 | [0] = MLX4_STEERING_DMFS_A0_DEFAULT, | ||
1771 | [1] = MLX4_STEERING_DMFS_A0_DYNAMIC, | ||
1772 | [2] = MLX4_STEERING_DMFS_A0_STATIC, | ||
1773 | [3] = MLX4_STEERING_DMFS_A0_DISABLE | ||
1774 | }; | ||
1737 | 1775 | ||
1738 | #define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 | 1776 | #define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 |
1739 | #define QUERY_HCA_CORE_CLOCK_OFFSET 0x0c | 1777 | #define QUERY_HCA_CORE_CLOCK_OFFSET 0x0c |
@@ -1786,6 +1824,10 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, | |||
1786 | INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); | 1824 | INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); |
1787 | MLX4_GET(param->log_mc_table_sz, outbox, | 1825 | MLX4_GET(param->log_mc_table_sz, outbox, |
1788 | INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); | 1826 | INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); |
1827 | MLX4_GET(byte_field, outbox, | ||
1828 | INIT_HCA_FS_A0_OFFSET); | ||
1829 | param->dmfs_high_steer_mode = | ||
1830 | a0_dmfs_query_hw_steering[(byte_field >> 6) & 3]; | ||
1789 | } else { | 1831 | } else { |
1790 | MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET); | 1832 | MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET); |
1791 | MLX4_GET(param->log_mc_entry_sz, outbox, | 1833 | MLX4_GET(param->log_mc_entry_sz, outbox, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 744398b7ab5e..794e2826609a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h | |||
@@ -60,6 +60,7 @@ struct mlx4_port_cap { | |||
60 | int vendor_oui; | 60 | int vendor_oui; |
61 | u16 wavelength; | 61 | u16 wavelength; |
62 | u64 trans_code; | 62 | u64 trans_code; |
63 | u8 dmfs_optimized_state; | ||
63 | }; | 64 | }; |
64 | 65 | ||
65 | struct mlx4_dev_cap { | 66 | struct mlx4_dev_cap { |
@@ -124,6 +125,8 @@ struct mlx4_dev_cap { | |||
124 | int max_gso_sz; | 125 | int max_gso_sz; |
125 | int max_rss_tbl_sz; | 126 | int max_rss_tbl_sz; |
126 | u32 max_counters; | 127 | u32 max_counters; |
128 | u32 dmfs_high_rate_qpn_base; | ||
129 | u32 dmfs_high_rate_qpn_range; | ||
127 | struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1]; | 130 | struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1]; |
128 | }; | 131 | }; |
129 | 132 | ||
@@ -194,6 +197,7 @@ struct mlx4_init_hca_param { | |||
194 | u8 mw_enabled; /* Enable memory windows */ | 197 | u8 mw_enabled; /* Enable memory windows */ |
195 | u8 uar_page_sz; /* log pg sz in 4k chunks */ | 198 | u8 uar_page_sz; /* log pg sz in 4k chunks */ |
196 | u8 steering_mode; /* for QUERY_HCA */ | 199 | u8 steering_mode; /* for QUERY_HCA */ |
200 | u8 dmfs_high_steer_mode; /* for QUERY_HCA */ | ||
197 | u64 dev_cap_enabled; | 201 | u64 dev_cap_enabled; |
198 | u16 cqe_size; /* For use only when CQE stride feature enabled */ | 202 | u16 cqe_size; /* For use only when CQE stride feature enabled */ |
199 | u16 eqe_size; /* For use only when EQE stride feature enabled */ | 203 | u16 eqe_size; /* For use only when EQE stride feature enabled */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 6173b8072988..e25436b24ce7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -105,7 +105,8 @@ MODULE_PARM_DESC(enable_64b_cqe_eqe, | |||
105 | "Enable 64 byte CQEs/EQEs when the FW supports this (default: True)"); | 105 | "Enable 64 byte CQEs/EQEs when the FW supports this (default: True)"); |
106 | 106 | ||
107 | #define PF_CONTEXT_BEHAVIOUR_MASK (MLX4_FUNC_CAP_64B_EQE_CQE | \ | 107 | #define PF_CONTEXT_BEHAVIOUR_MASK (MLX4_FUNC_CAP_64B_EQE_CQE | \ |
108 | MLX4_FUNC_CAP_EQE_CQE_STRIDE) | 108 | MLX4_FUNC_CAP_EQE_CQE_STRIDE | \ |
109 | MLX4_FUNC_CAP_DMFS_A0_STATIC) | ||
109 | 110 | ||
110 | static char mlx4_version[] = | 111 | static char mlx4_version[] = |
111 | DRV_NAME ": Mellanox ConnectX core driver v" | 112 | DRV_NAME ": Mellanox ConnectX core driver v" |
@@ -463,8 +464,28 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
463 | (1 << dev->caps.log_num_vlans) * | 464 | (1 << dev->caps.log_num_vlans) * |
464 | dev->caps.num_ports; | 465 | dev->caps.num_ports; |
465 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH] = MLX4_NUM_FEXCH; | 466 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_EXCH] = MLX4_NUM_FEXCH; |
467 | |||
468 | if (dev_cap->dmfs_high_rate_qpn_base > 0 && | ||
469 | dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FS_EN) | ||
470 | dev->caps.dmfs_high_rate_qpn_base = dev_cap->dmfs_high_rate_qpn_base; | ||
471 | else | ||
472 | dev->caps.dmfs_high_rate_qpn_base = | ||
473 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW]; | ||
474 | |||
475 | if (dev_cap->dmfs_high_rate_qpn_range > 0 && | ||
476 | dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FS_EN) { | ||
477 | dev->caps.dmfs_high_rate_qpn_range = dev_cap->dmfs_high_rate_qpn_range; | ||
478 | dev->caps.dmfs_high_steer_mode = MLX4_STEERING_DMFS_A0_DEFAULT; | ||
479 | dev->caps.flags2 |= MLX4_DEV_CAP_FLAG2_FS_A0; | ||
480 | } else { | ||
481 | dev->caps.dmfs_high_steer_mode = MLX4_STEERING_DMFS_A0_NOT_SUPPORTED; | ||
482 | dev->caps.dmfs_high_rate_qpn_base = | ||
483 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW]; | ||
484 | dev->caps.dmfs_high_rate_qpn_range = MLX4_A0_STEERING_TABLE_SIZE; | ||
485 | } | ||
486 | |||
466 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_RSS_RAW_ETH] = | 487 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_RSS_RAW_ETH] = |
467 | MLX4_A0_STEERING_TABLE_SIZE; | 488 | dev->caps.dmfs_high_rate_qpn_range; |
468 | 489 | ||
469 | dev->caps.reserved_qps = dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] + | 490 | dev->caps.reserved_qps = dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] + |
470 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] + | 491 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] + |
@@ -753,7 +774,8 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
753 | 774 | ||
754 | if ((func_cap.pf_context_behaviour | PF_CONTEXT_BEHAVIOUR_MASK) != | 775 | if ((func_cap.pf_context_behaviour | PF_CONTEXT_BEHAVIOUR_MASK) != |
755 | PF_CONTEXT_BEHAVIOUR_MASK) { | 776 | PF_CONTEXT_BEHAVIOUR_MASK) { |
756 | mlx4_err(dev, "Unknown pf context behaviour\n"); | 777 | mlx4_err(dev, "Unknown pf context behaviour %x known flags %x\n", |
778 | func_cap.pf_context_behaviour, PF_CONTEXT_BEHAVIOUR_MASK); | ||
757 | return -ENOSYS; | 779 | return -ENOSYS; |
758 | } | 780 | } |
759 | 781 | ||
@@ -1640,10 +1662,46 @@ static int choose_log_fs_mgm_entry_size(int qp_per_entry) | |||
1640 | return (i <= MLX4_MAX_MGM_LOG_ENTRY_SIZE) ? i : -1; | 1662 | return (i <= MLX4_MAX_MGM_LOG_ENTRY_SIZE) ? i : -1; |
1641 | } | 1663 | } |
1642 | 1664 | ||
1665 | static const char *dmfs_high_rate_steering_mode_str(int dmfs_high_steer_mode) | ||
1666 | { | ||
1667 | switch (dmfs_high_steer_mode) { | ||
1668 | case MLX4_STEERING_DMFS_A0_DEFAULT: | ||
1669 | return "default performance"; | ||
1670 | |||
1671 | case MLX4_STEERING_DMFS_A0_DYNAMIC: | ||
1672 | return "dynamic hybrid mode"; | ||
1673 | |||
1674 | case MLX4_STEERING_DMFS_A0_STATIC: | ||
1675 | return "performance optimized for limited rule configuration (static)"; | ||
1676 | |||
1677 | case MLX4_STEERING_DMFS_A0_DISABLE: | ||
1678 | return "disabled performance optimized steering"; | ||
1679 | |||
1680 | case MLX4_STEERING_DMFS_A0_NOT_SUPPORTED: | ||
1681 | return "performance optimized steering not supported"; | ||
1682 | |||
1683 | default: | ||
1684 | return "Unrecognized mode"; | ||
1685 | } | ||
1686 | } | ||
1687 | |||
1688 | #define MLX4_DMFS_A0_STEERING (1UL << 2) | ||
1689 | |||
1643 | static void choose_steering_mode(struct mlx4_dev *dev, | 1690 | static void choose_steering_mode(struct mlx4_dev *dev, |
1644 | struct mlx4_dev_cap *dev_cap) | 1691 | struct mlx4_dev_cap *dev_cap) |
1645 | { | 1692 | { |
1646 | if (mlx4_log_num_mgm_entry_size == -1 && | 1693 | if (mlx4_log_num_mgm_entry_size <= 0) { |
1694 | if ((-mlx4_log_num_mgm_entry_size) & MLX4_DMFS_A0_STEERING) { | ||
1695 | if (dev->caps.dmfs_high_steer_mode == | ||
1696 | MLX4_STEERING_DMFS_A0_NOT_SUPPORTED) | ||
1697 | mlx4_err(dev, "DMFS high rate mode not supported\n"); | ||
1698 | else | ||
1699 | dev->caps.dmfs_high_steer_mode = | ||
1700 | MLX4_STEERING_DMFS_A0_STATIC; | ||
1701 | } | ||
1702 | } | ||
1703 | |||
1704 | if (mlx4_log_num_mgm_entry_size <= 0 && | ||
1647 | dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_FS_EN && | 1705 | dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_FS_EN && |
1648 | (!mlx4_is_mfunc(dev) || | 1706 | (!mlx4_is_mfunc(dev) || |
1649 | (dev_cap->fs_max_num_qp_per_entry >= (dev->num_vfs + 1))) && | 1707 | (dev_cap->fs_max_num_qp_per_entry >= (dev->num_vfs + 1))) && |
@@ -1656,6 +1714,9 @@ static void choose_steering_mode(struct mlx4_dev *dev, | |||
1656 | dev->caps.fs_log_max_ucast_qp_range_size = | 1714 | dev->caps.fs_log_max_ucast_qp_range_size = |
1657 | dev_cap->fs_log_max_ucast_qp_range_size; | 1715 | dev_cap->fs_log_max_ucast_qp_range_size; |
1658 | } else { | 1716 | } else { |
1717 | if (dev->caps.dmfs_high_steer_mode != | ||
1718 | MLX4_STEERING_DMFS_A0_NOT_SUPPORTED) | ||
1719 | dev->caps.dmfs_high_steer_mode = MLX4_STEERING_DMFS_A0_DISABLE; | ||
1659 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && | 1720 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER && |
1660 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) | 1721 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) |
1661 | dev->caps.steering_mode = MLX4_STEERING_MODE_B0; | 1722 | dev->caps.steering_mode = MLX4_STEERING_MODE_B0; |
@@ -1682,7 +1743,8 @@ static void choose_tunnel_offload_mode(struct mlx4_dev *dev, | |||
1682 | struct mlx4_dev_cap *dev_cap) | 1743 | struct mlx4_dev_cap *dev_cap) |
1683 | { | 1744 | { |
1684 | if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED && | 1745 | if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED && |
1685 | dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) | 1746 | dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS && |
1747 | dev->caps.dmfs_high_steer_mode != MLX4_STEERING_DMFS_A0_STATIC) | ||
1686 | dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_VXLAN; | 1748 | dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_VXLAN; |
1687 | else | 1749 | else |
1688 | dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_NONE; | 1750 | dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_NONE; |
@@ -1691,6 +1753,35 @@ static void choose_tunnel_offload_mode(struct mlx4_dev *dev, | |||
1691 | == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) ? "vxlan" : "none"); | 1753 | == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) ? "vxlan" : "none"); |
1692 | } | 1754 | } |
1693 | 1755 | ||
1756 | static int mlx4_validate_optimized_steering(struct mlx4_dev *dev) | ||
1757 | { | ||
1758 | int i; | ||
1759 | struct mlx4_port_cap port_cap; | ||
1760 | |||
1761 | if (dev->caps.dmfs_high_steer_mode == MLX4_STEERING_DMFS_A0_NOT_SUPPORTED) | ||
1762 | return -EINVAL; | ||
1763 | |||
1764 | for (i = 1; i <= dev->caps.num_ports; i++) { | ||
1765 | if (mlx4_dev_port(dev, i, &port_cap)) { | ||
1766 | mlx4_err(dev, | ||
1767 | "QUERY_DEV_CAP command failed, can't veify DMFS high rate steering.\n"); | ||
1768 | } else if ((dev->caps.dmfs_high_steer_mode != | ||
1769 | MLX4_STEERING_DMFS_A0_DEFAULT) && | ||
1770 | (port_cap.dmfs_optimized_state == | ||
1771 | !!(dev->caps.dmfs_high_steer_mode == | ||
1772 | MLX4_STEERING_DMFS_A0_DISABLE))) { | ||
1773 | mlx4_err(dev, | ||
1774 | "DMFS high rate steer mode differ, driver requested %s but %s in FW.\n", | ||
1775 | dmfs_high_rate_steering_mode_str( | ||
1776 | dev->caps.dmfs_high_steer_mode), | ||
1777 | (port_cap.dmfs_optimized_state ? | ||
1778 | "enabled" : "disabled")); | ||
1779 | } | ||
1780 | } | ||
1781 | |||
1782 | return 0; | ||
1783 | } | ||
1784 | |||
1694 | static int mlx4_init_fw(struct mlx4_dev *dev) | 1785 | static int mlx4_init_fw(struct mlx4_dev *dev) |
1695 | { | 1786 | { |
1696 | struct mlx4_mod_stat_cfg mlx4_cfg; | 1787 | struct mlx4_mod_stat_cfg mlx4_cfg; |
@@ -1743,6 +1834,10 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1743 | choose_steering_mode(dev, &dev_cap); | 1834 | choose_steering_mode(dev, &dev_cap); |
1744 | choose_tunnel_offload_mode(dev, &dev_cap); | 1835 | choose_tunnel_offload_mode(dev, &dev_cap); |
1745 | 1836 | ||
1837 | if (dev->caps.dmfs_high_steer_mode == MLX4_STEERING_DMFS_A0_STATIC && | ||
1838 | mlx4_is_master(dev)) | ||
1839 | dev->caps.function_caps |= MLX4_FUNC_CAP_DMFS_A0_STATIC; | ||
1840 | |||
1746 | err = mlx4_get_phys_port_id(dev); | 1841 | err = mlx4_get_phys_port_id(dev); |
1747 | if (err) | 1842 | if (err) |
1748 | mlx4_err(dev, "Fail to get physical port id\n"); | 1843 | mlx4_err(dev, "Fail to get physical port id\n"); |
@@ -1829,6 +1924,24 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1829 | mlx4_err(dev, "Failed to map internal clock. Timestamping is not supported\n"); | 1924 | mlx4_err(dev, "Failed to map internal clock. Timestamping is not supported\n"); |
1830 | } | 1925 | } |
1831 | } | 1926 | } |
1927 | |||
1928 | if (dev->caps.dmfs_high_steer_mode != | ||
1929 | MLX4_STEERING_DMFS_A0_NOT_SUPPORTED) { | ||
1930 | if (mlx4_validate_optimized_steering(dev)) | ||
1931 | mlx4_warn(dev, "Optimized steering validation failed\n"); | ||
1932 | |||
1933 | if (dev->caps.dmfs_high_steer_mode == | ||
1934 | MLX4_STEERING_DMFS_A0_DISABLE) { | ||
1935 | dev->caps.dmfs_high_rate_qpn_base = | ||
1936 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW]; | ||
1937 | dev->caps.dmfs_high_rate_qpn_range = | ||
1938 | MLX4_A0_STEERING_TABLE_SIZE; | ||
1939 | } | ||
1940 | |||
1941 | mlx4_dbg(dev, "DMFS high rate steer mode is: %s\n", | ||
1942 | dmfs_high_rate_steering_mode_str( | ||
1943 | dev->caps.dmfs_high_steer_mode)); | ||
1944 | } | ||
1832 | } else { | 1945 | } else { |
1833 | err = mlx4_init_slave(dev); | 1946 | err = mlx4_init_slave(dev); |
1834 | if (err) { | 1947 | if (err) { |
@@ -3201,10 +3314,11 @@ static int __init mlx4_verify_params(void) | |||
3201 | port_type_array[0] = true; | 3314 | port_type_array[0] = true; |
3202 | } | 3315 | } |
3203 | 3316 | ||
3204 | if (mlx4_log_num_mgm_entry_size != -1 && | 3317 | if (mlx4_log_num_mgm_entry_size < -7 || |
3205 | (mlx4_log_num_mgm_entry_size < MLX4_MIN_MGM_LOG_ENTRY_SIZE || | 3318 | (mlx4_log_num_mgm_entry_size > 0 && |
3206 | mlx4_log_num_mgm_entry_size > MLX4_MAX_MGM_LOG_ENTRY_SIZE)) { | 3319 | (mlx4_log_num_mgm_entry_size < MLX4_MIN_MGM_LOG_ENTRY_SIZE || |
3207 | pr_warn("mlx4_core: mlx4_log_num_mgm_entry_size (%d) not in legal range (-1 or %d..%d)\n", | 3320 | mlx4_log_num_mgm_entry_size > MLX4_MAX_MGM_LOG_ENTRY_SIZE))) { |
3321 | pr_warn("mlx4_core: mlx4_log_num_mgm_entry_size (%d) not in legal range (-7..0 or %d..%d)\n", | ||
3208 | mlx4_log_num_mgm_entry_size, | 3322 | mlx4_log_num_mgm_entry_size, |
3209 | MLX4_MIN_MGM_LOG_ENTRY_SIZE, | 3323 | MLX4_MIN_MGM_LOG_ENTRY_SIZE, |
3210 | MLX4_MAX_MGM_LOG_ENTRY_SIZE); | 3324 | MLX4_MAX_MGM_LOG_ENTRY_SIZE); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index cebd1180702b..bdd4eea2247c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -689,8 +689,6 @@ enum mlx4_qp_table_zones { | |||
689 | MLX4_QP_TABLE_ZONE_NUM | 689 | MLX4_QP_TABLE_ZONE_NUM |
690 | }; | 690 | }; |
691 | 691 | ||
692 | #define MLX4_A0_STEERING_TABLE_SIZE 256 | ||
693 | |||
694 | struct mlx4_qp_table { | 692 | struct mlx4_qp_table { |
695 | struct mlx4_bitmap *bitmap_gen; | 693 | struct mlx4_bitmap *bitmap_gen; |
696 | struct mlx4_zone_allocator *zones; | 694 | struct mlx4_zone_allocator *zones; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index d8d040c366f4..1586ecce13c7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c | |||
@@ -712,8 +712,8 @@ int mlx4_init_qp_table(struct mlx4_dev *dev) | |||
712 | int k; | 712 | int k; |
713 | int fixed_reserved_from_bot_rv = 0; | 713 | int fixed_reserved_from_bot_rv = 0; |
714 | int bottom_reserved_for_rss_bitmap; | 714 | int bottom_reserved_for_rss_bitmap; |
715 | u32 max_table_offset = dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] + | 715 | u32 max_table_offset = dev->caps.dmfs_high_rate_qpn_base + |
716 | MLX4_A0_STEERING_TABLE_SIZE; | 716 | dev->caps.dmfs_high_rate_qpn_range; |
717 | 717 | ||
718 | spin_lock_init(&qp_table->lock); | 718 | spin_lock_init(&qp_table->lock); |
719 | INIT_RADIX_TREE(&dev->qp_table_tree, GFP_ATOMIC); | 719 | INIT_RADIX_TREE(&dev->qp_table_tree, GFP_ATOMIC); |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 39890cddc5fa..25c791e295fd 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -117,6 +117,14 @@ enum { | |||
117 | MLX4_STEERING_MODE_DEVICE_MANAGED | 117 | MLX4_STEERING_MODE_DEVICE_MANAGED |
118 | }; | 118 | }; |
119 | 119 | ||
120 | enum { | ||
121 | MLX4_STEERING_DMFS_A0_DEFAULT, | ||
122 | MLX4_STEERING_DMFS_A0_DYNAMIC, | ||
123 | MLX4_STEERING_DMFS_A0_STATIC, | ||
124 | MLX4_STEERING_DMFS_A0_DISABLE, | ||
125 | MLX4_STEERING_DMFS_A0_NOT_SUPPORTED | ||
126 | }; | ||
127 | |||
120 | static inline const char *mlx4_steering_mode_str(int steering_mode) | 128 | static inline const char *mlx4_steering_mode_str(int steering_mode) |
121 | { | 129 | { |
122 | switch (steering_mode) { | 130 | switch (steering_mode) { |
@@ -191,7 +199,8 @@ enum { | |||
191 | MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP = 1LL << 15, | 199 | MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP = 1LL << 15, |
192 | MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16, | 200 | MLX4_DEV_CAP_FLAG2_CONFIG_DEV = 1LL << 16, |
193 | MLX4_DEV_CAP_FLAG2_SYS_EQS = 1LL << 17, | 201 | MLX4_DEV_CAP_FLAG2_SYS_EQS = 1LL << 17, |
194 | MLX4_DEV_CAP_FLAG2_80_VFS = 1LL << 18 | 202 | MLX4_DEV_CAP_FLAG2_80_VFS = 1LL << 18, |
203 | MLX4_DEV_CAP_FLAG2_FS_A0 = 1LL << 19 | ||
195 | }; | 204 | }; |
196 | 205 | ||
197 | enum { | 206 | enum { |
@@ -225,7 +234,8 @@ enum { | |||
225 | 234 | ||
226 | enum { | 235 | enum { |
227 | MLX4_FUNC_CAP_64B_EQE_CQE = 1L << 0, | 236 | MLX4_FUNC_CAP_64B_EQE_CQE = 1L << 0, |
228 | MLX4_FUNC_CAP_EQE_CQE_STRIDE = 1L << 1 | 237 | MLX4_FUNC_CAP_EQE_CQE_STRIDE = 1L << 1, |
238 | MLX4_FUNC_CAP_DMFS_A0_STATIC = 1L << 2 | ||
229 | }; | 239 | }; |
230 | 240 | ||
231 | 241 | ||
@@ -482,6 +492,7 @@ struct mlx4_caps { | |||
482 | int reserved_mcgs; | 492 | int reserved_mcgs; |
483 | int num_qp_per_mgm; | 493 | int num_qp_per_mgm; |
484 | int steering_mode; | 494 | int steering_mode; |
495 | int dmfs_high_steer_mode; | ||
485 | int fs_log_max_ucast_qp_range_size; | 496 | int fs_log_max_ucast_qp_range_size; |
486 | int num_pds; | 497 | int num_pds; |
487 | int reserved_pds; | 498 | int reserved_pds; |
@@ -522,6 +533,8 @@ struct mlx4_caps { | |||
522 | int tunnel_offload_mode; | 533 | int tunnel_offload_mode; |
523 | u8 rx_checksum_flags_port[MLX4_MAX_PORTS + 1]; | 534 | u8 rx_checksum_flags_port[MLX4_MAX_PORTS + 1]; |
524 | u8 alloc_res_qp_mask; | 535 | u8 alloc_res_qp_mask; |
536 | u32 dmfs_high_rate_qpn_base; | ||
537 | u32 dmfs_high_rate_qpn_range; | ||
525 | }; | 538 | }; |
526 | 539 | ||
527 | struct mlx4_buf_list { | 540 | struct mlx4_buf_list { |