diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 17:50:12 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 17:50:12 -0400 |
| commit | ece236ce2fad9c27a6fd2530f899289025194bce (patch) | |
| tree | 474b793205872206a2a3f7d409ff9b1f81f3a9a8 /drivers/net/mlx4 | |
| parent | 441c196e84b11aad3123baa9320eee7abc6b5c98 (diff) | |
| parent | 4460207561290c3be7e6c7538f22690028170c1d (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (26 commits)
IB/qib: Defer HCA error events to tasklet
mlx4_core: Bump the driver version to 1.0
RDMA/cxgb4: Use printk_ratelimited() instead of printk_ratelimit()
IB/mlx4: Support PMA counters for IBoE
IB/mlx4: Use flow counters on IBoE ports
IB/pma: Add include file for IBA performance counters definitions
mlx4_core: Add network flow counters
mlx4_core: Fix location of counter index in QP context struct
mlx4_core: Read extended capabilities into the flags field
mlx4_core: Extend capability flags to 64 bits
IB/mlx4: Generate GID change events in IBoE code
IB/core: Add GID change event
RDMA/cma: Don't allow IPoIB port space for IBoE
RDMA: Allow for NULL .modify_device() and .modify_port() methods
IB/qib: Update active link width
IB/qib: Fix potential deadlock with link down interrupt
IB/qib: Add sysfs interface to read free contexts
IB/mthca: Remove unnecessary read of PCI_CAP_ID_EXP
IB/qib: Remove double define
IB/qib: Remove unnecessary read of PCI_CAP_ID_EXP
...
Diffstat (limited to 'drivers/net/mlx4')
| -rw-r--r-- | drivers/net/mlx4/en_ethtool.c | 9 | ||||
| -rw-r--r-- | drivers/net/mlx4/en_main.c | 3 | ||||
| -rw-r--r-- | drivers/net/mlx4/en_netdev.c | 5 | ||||
| -rw-r--r-- | drivers/net/mlx4/en_port.c | 6 | ||||
| -rw-r--r-- | drivers/net/mlx4/en_selftest.c | 3 | ||||
| -rw-r--r-- | drivers/net/mlx4/fw.c | 39 | ||||
| -rw-r--r-- | drivers/net/mlx4/fw.h | 8 | ||||
| -rw-r--r-- | drivers/net/mlx4/main.c | 58 | ||||
| -rw-r--r-- | drivers/net/mlx4/mcg.c | 17 | ||||
| -rw-r--r-- | drivers/net/mlx4/mlx4.h | 5 | ||||
| -rw-r--r-- | drivers/net/mlx4/port.c | 8 |
11 files changed, 112 insertions, 49 deletions
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index 2e858e4dcf4..eb096253d78 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c | |||
| @@ -104,7 +104,7 @@ static void mlx4_en_get_wol(struct net_device *netdev, | |||
| 104 | int err = 0; | 104 | int err = 0; |
| 105 | u64 config = 0; | 105 | u64 config = 0; |
| 106 | 106 | ||
| 107 | if (!priv->mdev->dev->caps.wol) { | 107 | if (!(priv->mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_WOL)) { |
| 108 | wol->supported = 0; | 108 | wol->supported = 0; |
| 109 | wol->wolopts = 0; | 109 | wol->wolopts = 0; |
| 110 | return; | 110 | return; |
| @@ -134,7 +134,7 @@ static int mlx4_en_set_wol(struct net_device *netdev, | |||
| 134 | u64 config = 0; | 134 | u64 config = 0; |
| 135 | int err = 0; | 135 | int err = 0; |
| 136 | 136 | ||
| 137 | if (!priv->mdev->dev->caps.wol) | 137 | if (!(priv->mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_WOL)) |
| 138 | return -EOPNOTSUPP; | 138 | return -EOPNOTSUPP; |
| 139 | 139 | ||
| 140 | if (wol->supported & ~WAKE_MAGIC) | 140 | if (wol->supported & ~WAKE_MAGIC) |
| @@ -170,7 +170,8 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset) | |||
| 170 | return NUM_ALL_STATS + | 170 | return NUM_ALL_STATS + |
| 171 | (priv->tx_ring_num + priv->rx_ring_num) * 2; | 171 | (priv->tx_ring_num + priv->rx_ring_num) * 2; |
| 172 | case ETH_SS_TEST: | 172 | case ETH_SS_TEST: |
| 173 | return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.loopback_support) * 2; | 173 | return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags |
| 174 | & MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2; | ||
| 174 | default: | 175 | default: |
| 175 | return -EOPNOTSUPP; | 176 | return -EOPNOTSUPP; |
| 176 | } | 177 | } |
| @@ -220,7 +221,7 @@ static void mlx4_en_get_strings(struct net_device *dev, | |||
| 220 | case ETH_SS_TEST: | 221 | case ETH_SS_TEST: |
| 221 | for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++) | 222 | for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++) |
| 222 | strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); | 223 | strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); |
| 223 | if (priv->mdev->dev->caps.loopback_support) | 224 | if (priv->mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_UC_LOOPBACK) |
| 224 | for (; i < MLX4_EN_NUM_SELF_TEST; i++) | 225 | for (; i < MLX4_EN_NUM_SELF_TEST; i++) |
| 225 | strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); | 226 | strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); |
| 226 | break; | 227 | break; |
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c index 9276b1b2558..6bfea233a9f 100644 --- a/drivers/net/mlx4/en_main.c +++ b/drivers/net/mlx4/en_main.c | |||
| @@ -106,7 +106,8 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) | |||
| 106 | 106 | ||
| 107 | params->tcp_rss = tcp_rss; | 107 | params->tcp_rss = tcp_rss; |
| 108 | params->udp_rss = udp_rss; | 108 | params->udp_rss = udp_rss; |
| 109 | if (params->udp_rss && !mdev->dev->caps.udp_rss) { | 109 | if (params->udp_rss && !(mdev->dev->caps.flags |
| 110 | & MLX4_DEV_CAP_FLAG_UDP_RSS)) { | ||
| 110 | mlx4_warn(mdev, "UDP RSS is not supported on this device.\n"); | 111 | mlx4_warn(mdev, "UDP RSS is not supported on this device.\n"); |
| 111 | params->udp_rss = 0; | 112 | params->udp_rss = 0; |
| 112 | } | 113 | } |
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 9d3f57e76f2..4b0f32e568f 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c | |||
| @@ -215,7 +215,8 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
| 215 | priv->flags |= MLX4_EN_FLAG_PROMISC; | 215 | priv->flags |= MLX4_EN_FLAG_PROMISC; |
| 216 | 216 | ||
| 217 | /* Enable promiscouos mode */ | 217 | /* Enable promiscouos mode */ |
| 218 | if (!mdev->dev->caps.vep_uc_steering) | 218 | if (!(mdev->dev->caps.flags & |
| 219 | MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) | ||
| 219 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, | 220 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, |
| 220 | priv->base_qpn, 1); | 221 | priv->base_qpn, 1); |
| 221 | else | 222 | else |
| @@ -259,7 +260,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
| 259 | priv->flags &= ~MLX4_EN_FLAG_PROMISC; | 260 | priv->flags &= ~MLX4_EN_FLAG_PROMISC; |
| 260 | 261 | ||
| 261 | /* Disable promiscouos mode */ | 262 | /* Disable promiscouos mode */ |
| 262 | if (!mdev->dev->caps.vep_uc_steering) | 263 | if (!(mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) |
| 263 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, | 264 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, |
| 264 | priv->base_qpn, 0); | 265 | priv->base_qpn, 0); |
| 265 | else | 266 | else |
diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c index 2a74bc81b9f..5e710917806 100644 --- a/drivers/net/mlx4/en_port.c +++ b/drivers/net/mlx4/en_port.c | |||
| @@ -114,9 +114,11 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, | |||
| 114 | struct mlx4_set_port_rqp_calc_context *context; | 114 | struct mlx4_set_port_rqp_calc_context *context; |
| 115 | int err; | 115 | int err; |
| 116 | u32 in_mod; | 116 | u32 in_mod; |
| 117 | u32 m_promisc = (dev->caps.vep_mc_steering) ? MCAST_DIRECT : MCAST_DEFAULT; | 117 | u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ? |
| 118 | MCAST_DIRECT : MCAST_DEFAULT; | ||
| 118 | 119 | ||
| 119 | if (dev->caps.vep_mc_steering && dev->caps.vep_uc_steering) | 120 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER && |
| 121 | dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) | ||
| 120 | return 0; | 122 | return 0; |
| 121 | 123 | ||
| 122 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 124 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
diff --git a/drivers/net/mlx4/en_selftest.c b/drivers/net/mlx4/en_selftest.c index 191a8dcd8a9..9fdbcecd499 100644 --- a/drivers/net/mlx4/en_selftest.c +++ b/drivers/net/mlx4/en_selftest.c | |||
| @@ -159,7 +159,8 @@ retry_tx: | |||
| 159 | goto retry_tx; | 159 | goto retry_tx; |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | if (priv->mdev->dev->caps.loopback_support){ | 162 | if (priv->mdev->dev->caps.flags & |
| 163 | MLX4_DEV_CAP_FLAG_UC_LOOPBACK) { | ||
| 163 | buf[3] = mlx4_en_test_registers(priv); | 164 | buf[3] = mlx4_en_test_registers(priv); |
| 164 | buf[4] = mlx4_en_test_loopback(priv); | 165 | buf[4] = mlx4_en_test_loopback(priv); |
| 165 | } | 166 | } |
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index 67a209ba939..7eb8ba822e9 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c | |||
| @@ -75,7 +75,7 @@ MODULE_PARM_DESC(enable_qos, "Enable Quality of Service support in the HCA (defa | |||
| 75 | } \ | 75 | } \ |
| 76 | } while (0) | 76 | } while (0) |
| 77 | 77 | ||
| 78 | static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 flags) | 78 | static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags) |
| 79 | { | 79 | { |
| 80 | static const char *fname[] = { | 80 | static const char *fname[] = { |
| 81 | [ 0] = "RC transport", | 81 | [ 0] = "RC transport", |
| @@ -99,13 +99,19 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 flags) | |||
| 99 | [21] = "UD multicast support", | 99 | [21] = "UD multicast support", |
| 100 | [24] = "Demand paging support", | 100 | [24] = "Demand paging support", |
| 101 | [25] = "Router support", | 101 | [25] = "Router support", |
| 102 | [30] = "IBoE support" | 102 | [30] = "IBoE support", |
| 103 | [32] = "Unicast loopback support", | ||
| 104 | [38] = "Wake On LAN support", | ||
| 105 | [40] = "UDP RSS support", | ||
| 106 | [41] = "Unicast VEP steering support", | ||
| 107 | [42] = "Multicast VEP steering support", | ||
| 108 | [48] = "Counters support", | ||
| 103 | }; | 109 | }; |
| 104 | int i; | 110 | int i; |
| 105 | 111 | ||
| 106 | mlx4_dbg(dev, "DEV_CAP flags:\n"); | 112 | mlx4_dbg(dev, "DEV_CAP flags:\n"); |
| 107 | for (i = 0; i < ARRAY_SIZE(fname); ++i) | 113 | for (i = 0; i < ARRAY_SIZE(fname); ++i) |
| 108 | if (fname[i] && (flags & (1 << i))) | 114 | if (fname[i] && (flags & (1LL << i))) |
| 109 | mlx4_dbg(dev, " %s\n", fname[i]); | 115 | mlx4_dbg(dev, " %s\n", fname[i]); |
| 110 | } | 116 | } |
| 111 | 117 | ||
| @@ -142,7 +148,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 142 | struct mlx4_cmd_mailbox *mailbox; | 148 | struct mlx4_cmd_mailbox *mailbox; |
| 143 | u32 *outbox; | 149 | u32 *outbox; |
| 144 | u8 field; | 150 | u8 field; |
| 145 | u32 field32; | 151 | u32 field32, flags, ext_flags; |
| 146 | u16 size; | 152 | u16 size; |
| 147 | u16 stat_rate; | 153 | u16 stat_rate; |
| 148 | int err; | 154 | int err; |
| @@ -180,8 +186,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 180 | #define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b | 186 | #define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b |
| 181 | #define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c | 187 | #define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c |
| 182 | #define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f | 188 | #define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f |
| 183 | #define QUERY_DEV_CAP_UDP_RSS_OFFSET 0x42 | 189 | #define QUERY_DEV_CAP_EXT_FLAGS_OFFSET 0x40 |
| 184 | #define QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET 0x43 | ||
| 185 | #define QUERY_DEV_CAP_FLAGS_OFFSET 0x44 | 190 | #define QUERY_DEV_CAP_FLAGS_OFFSET 0x44 |
| 186 | #define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48 | 191 | #define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48 |
| 187 | #define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49 | 192 | #define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49 |
| @@ -199,6 +204,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 199 | #define QUERY_DEV_CAP_MAX_MCG_OFFSET 0x63 | 204 | #define QUERY_DEV_CAP_MAX_MCG_OFFSET 0x63 |
| 200 | #define QUERY_DEV_CAP_RSVD_PD_OFFSET 0x64 | 205 | #define QUERY_DEV_CAP_RSVD_PD_OFFSET 0x64 |
| 201 | #define QUERY_DEV_CAP_MAX_PD_OFFSET 0x65 | 206 | #define QUERY_DEV_CAP_MAX_PD_OFFSET 0x65 |
| 207 | #define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68 | ||
| 202 | #define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 | 208 | #define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 |
| 203 | #define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 | 209 | #define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 |
| 204 | #define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84 | 210 | #define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84 |
| @@ -272,14 +278,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 272 | dev_cap->max_msg_sz = 1 << (field & 0x1f); | 278 | dev_cap->max_msg_sz = 1 << (field & 0x1f); |
| 273 | MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); | 279 | MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); |
| 274 | dev_cap->stat_rate_support = stat_rate; | 280 | dev_cap->stat_rate_support = stat_rate; |
| 275 | MLX4_GET(field, outbox, QUERY_DEV_CAP_UDP_RSS_OFFSET); | 281 | MLX4_GET(ext_flags, outbox, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); |
| 276 | dev_cap->udp_rss = field & 0x1; | 282 | MLX4_GET(flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); |
| 277 | dev_cap->vep_uc_steering = field & 0x2; | 283 | dev_cap->flags = flags | (u64)ext_flags << 32; |
| 278 | dev_cap->vep_mc_steering = field & 0x4; | ||
| 279 | MLX4_GET(field, outbox, QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET); | ||
| 280 | dev_cap->loopback_support = field & 0x1; | ||
| 281 | dev_cap->wol = field & 0x40; | ||
| 282 | MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); | ||
| 283 | MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET); | 284 | MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET); |
| 284 | dev_cap->reserved_uars = field >> 4; | 285 | dev_cap->reserved_uars = field >> 4; |
| 285 | MLX4_GET(field, outbox, QUERY_DEV_CAP_UAR_SZ_OFFSET); | 286 | MLX4_GET(field, outbox, QUERY_DEV_CAP_UAR_SZ_OFFSET); |
| @@ -356,6 +357,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 356 | QUERY_DEV_CAP_RSVD_LKEY_OFFSET); | 357 | QUERY_DEV_CAP_RSVD_LKEY_OFFSET); |
| 357 | MLX4_GET(dev_cap->max_icm_sz, outbox, | 358 | MLX4_GET(dev_cap->max_icm_sz, outbox, |
| 358 | QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET); | 359 | QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET); |
| 360 | if (dev_cap->flags & MLX4_DEV_CAP_FLAG_COUNTERS) | ||
| 361 | MLX4_GET(dev_cap->max_counters, outbox, | ||
| 362 | QUERY_DEV_CAP_MAX_COUNTERS_OFFSET); | ||
| 359 | 363 | ||
| 360 | if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { | 364 | if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { |
| 361 | for (i = 1; i <= dev_cap->num_ports; ++i) { | 365 | for (i = 1; i <= dev_cap->num_ports; ++i) { |
| @@ -449,6 +453,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 449 | mlx4_dbg(dev, "Max RQ desc size: %d, max RQ S/G: %d\n", | 453 | mlx4_dbg(dev, "Max RQ desc size: %d, max RQ S/G: %d\n", |
| 450 | dev_cap->max_rq_desc_sz, dev_cap->max_rq_sg); | 454 | dev_cap->max_rq_desc_sz, dev_cap->max_rq_sg); |
| 451 | mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz); | 455 | mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz); |
| 456 | mlx4_dbg(dev, "Max counters: %d\n", dev_cap->max_counters); | ||
| 452 | 457 | ||
| 453 | dump_dev_cap_flags(dev, dev_cap->flags); | 458 | dump_dev_cap_flags(dev, dev_cap->flags); |
| 454 | 459 | ||
| @@ -781,6 +786,10 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
| 781 | if (enable_qos) | 786 | if (enable_qos) |
| 782 | *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 2); | 787 | *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 2); |
| 783 | 788 | ||
| 789 | /* enable counters */ | ||
| 790 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS) | ||
| 791 | *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 4); | ||
| 792 | |||
| 784 | /* QPC/EEC/CQC/EQC/RDMARC attributes */ | 793 | /* QPC/EEC/CQC/EQC/RDMARC attributes */ |
| 785 | 794 | ||
| 786 | MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); | 795 | MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); |
| @@ -801,7 +810,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) | |||
| 801 | MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); | 810 | MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); |
| 802 | MLX4_PUT(inbox, param->log_mc_entry_sz, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); | 811 | MLX4_PUT(inbox, param->log_mc_entry_sz, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); |
| 803 | MLX4_PUT(inbox, param->log_mc_hash_sz, INIT_HCA_LOG_MC_HASH_SZ_OFFSET); | 812 | MLX4_PUT(inbox, param->log_mc_hash_sz, INIT_HCA_LOG_MC_HASH_SZ_OFFSET); |
| 804 | if (dev->caps.vep_mc_steering) | 813 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) |
| 805 | MLX4_PUT(inbox, (u8) (1 << 3), INIT_HCA_UC_STEERING_OFFSET); | 814 | MLX4_PUT(inbox, (u8) (1 << 3), INIT_HCA_UC_STEERING_OFFSET); |
| 806 | MLX4_PUT(inbox, param->log_mc_table_sz, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); | 815 | MLX4_PUT(inbox, param->log_mc_table_sz, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); |
| 807 | 816 | ||
diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h index 88003ebc618..1e8ecc3708e 100644 --- a/drivers/net/mlx4/fw.h +++ b/drivers/net/mlx4/fw.h | |||
| @@ -78,12 +78,7 @@ struct mlx4_dev_cap { | |||
| 78 | u16 wavelength[MLX4_MAX_PORTS + 1]; | 78 | u16 wavelength[MLX4_MAX_PORTS + 1]; |
| 79 | u64 trans_code[MLX4_MAX_PORTS + 1]; | 79 | u64 trans_code[MLX4_MAX_PORTS + 1]; |
| 80 | u16 stat_rate_support; | 80 | u16 stat_rate_support; |
| 81 | int udp_rss; | 81 | u64 flags; |
| 82 | int loopback_support; | ||
| 83 | int vep_uc_steering; | ||
| 84 | int vep_mc_steering; | ||
| 85 | int wol; | ||
| 86 | u32 flags; | ||
| 87 | int reserved_uars; | 82 | int reserved_uars; |
| 88 | int uar_size; | 83 | int uar_size; |
| 89 | int min_page_sz; | 84 | int min_page_sz; |
| @@ -116,6 +111,7 @@ struct mlx4_dev_cap { | |||
| 116 | u8 supported_port_types[MLX4_MAX_PORTS + 1]; | 111 | u8 supported_port_types[MLX4_MAX_PORTS + 1]; |
| 117 | u8 log_max_macs[MLX4_MAX_PORTS + 1]; | 112 | u8 log_max_macs[MLX4_MAX_PORTS + 1]; |
| 118 | u8 log_max_vlans[MLX4_MAX_PORTS + 1]; | 113 | u8 log_max_vlans[MLX4_MAX_PORTS + 1]; |
| 114 | u32 max_counters; | ||
| 119 | }; | 115 | }; |
| 120 | 116 | ||
| 121 | struct mlx4_adapter { | 117 | struct mlx4_adapter { |
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 0cb0431ee19..c94b3426d35 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
| @@ -143,6 +143,7 @@ static void mlx4_set_port_mask(struct mlx4_dev *dev) | |||
| 143 | if (dev->caps.port_type[i] == MLX4_PORT_TYPE_IB) | 143 | if (dev->caps.port_type[i] == MLX4_PORT_TYPE_IB) |
| 144 | dev->caps.port_mask |= 1 << (i - 1); | 144 | dev->caps.port_mask |= 1 << (i - 1); |
| 145 | } | 145 | } |
| 146 | |||
| 146 | static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | 147 | static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) |
| 147 | { | 148 | { |
| 148 | int err; | 149 | int err; |
| @@ -226,11 +227,6 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 226 | dev->caps.bmme_flags = dev_cap->bmme_flags; | 227 | dev->caps.bmme_flags = dev_cap->bmme_flags; |
| 227 | dev->caps.reserved_lkey = dev_cap->reserved_lkey; | 228 | dev->caps.reserved_lkey = dev_cap->reserved_lkey; |
| 228 | dev->caps.stat_rate_support = dev_cap->stat_rate_support; | 229 | dev->caps.stat_rate_support = dev_cap->stat_rate_support; |
| 229 | dev->caps.udp_rss = dev_cap->udp_rss; | ||
| 230 | dev->caps.loopback_support = dev_cap->loopback_support; | ||
| 231 | dev->caps.vep_uc_steering = dev_cap->vep_uc_steering; | ||
| 232 | dev->caps.vep_mc_steering = dev_cap->vep_mc_steering; | ||
| 233 | dev->caps.wol = dev_cap->wol; | ||
| 234 | dev->caps.max_gso_sz = dev_cap->max_gso_sz; | 230 | dev->caps.max_gso_sz = dev_cap->max_gso_sz; |
| 235 | 231 | ||
| 236 | dev->caps.log_num_macs = log_num_mac; | 232 | dev->caps.log_num_macs = log_num_mac; |
| @@ -262,6 +258,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
| 262 | 258 | ||
| 263 | mlx4_set_port_mask(dev); | 259 | mlx4_set_port_mask(dev); |
| 264 | 260 | ||
| 261 | dev->caps.max_counters = 1 << ilog2(dev_cap->max_counters); | ||
| 262 | |||
| 265 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] = dev_cap->reserved_qps; | 263 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] = dev_cap->reserved_qps; |
| 266 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] = | 264 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] = |
| 267 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_ADDR] = | 265 | dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_ADDR] = |
| @@ -839,6 +837,45 @@ err_stop_fw: | |||
| 839 | return err; | 837 | return err; |
| 840 | } | 838 | } |
| 841 | 839 | ||
| 840 | static int mlx4_init_counters_table(struct mlx4_dev *dev) | ||
| 841 | { | ||
| 842 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
| 843 | int nent; | ||
| 844 | |||
| 845 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS)) | ||
| 846 | return -ENOENT; | ||
| 847 | |||
| 848 | nent = dev->caps.max_counters; | ||
| 849 | return mlx4_bitmap_init(&priv->counters_bitmap, nent, nent - 1, 0, 0); | ||
| 850 | } | ||
| 851 | |||
| 852 | static void mlx4_cleanup_counters_table(struct mlx4_dev *dev) | ||
| 853 | { | ||
| 854 | mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap); | ||
| 855 | } | ||
| 856 | |||
| 857 | int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx) | ||
| 858 | { | ||
| 859 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
| 860 | |||
| 861 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS)) | ||
| 862 | return -ENOENT; | ||
| 863 | |||
| 864 | *idx = mlx4_bitmap_alloc(&priv->counters_bitmap); | ||
| 865 | if (*idx == -1) | ||
| 866 | return -ENOMEM; | ||
| 867 | |||
| 868 | return 0; | ||
| 869 | } | ||
| 870 | EXPORT_SYMBOL_GPL(mlx4_counter_alloc); | ||
| 871 | |||
| 872 | void mlx4_counter_free(struct mlx4_dev *dev, u32 idx) | ||
| 873 | { | ||
| 874 | mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx); | ||
| 875 | return; | ||
| 876 | } | ||
| 877 | EXPORT_SYMBOL_GPL(mlx4_counter_free); | ||
| 878 | |||
| 842 | static int mlx4_setup_hca(struct mlx4_dev *dev) | 879 | static int mlx4_setup_hca(struct mlx4_dev *dev) |
| 843 | { | 880 | { |
| 844 | struct mlx4_priv *priv = mlx4_priv(dev); | 881 | struct mlx4_priv *priv = mlx4_priv(dev); |
| @@ -943,6 +980,12 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
| 943 | goto err_qp_table_free; | 980 | goto err_qp_table_free; |
| 944 | } | 981 | } |
| 945 | 982 | ||
| 983 | err = mlx4_init_counters_table(dev); | ||
| 984 | if (err && err != -ENOENT) { | ||
| 985 | mlx4_err(dev, "Failed to initialize counters table, aborting.\n"); | ||
| 986 | goto err_counters_table_free; | ||
| 987 | } | ||
| 988 | |||
| 946 | for (port = 1; port <= dev->caps.num_ports; port++) { | 989 | for (port = 1; port <= dev->caps.num_ports; port++) { |
| 947 | enum mlx4_port_type port_type = 0; | 990 | enum mlx4_port_type port_type = 0; |
| 948 | mlx4_SENSE_PORT(dev, port, &port_type); | 991 | mlx4_SENSE_PORT(dev, port, &port_type); |
| @@ -969,6 +1012,9 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
| 969 | err_mcg_table_free: | 1012 | err_mcg_table_free: |
| 970 | mlx4_cleanup_mcg_table(dev); | 1013 | mlx4_cleanup_mcg_table(dev); |
| 971 | 1014 | ||
| 1015 | err_counters_table_free: | ||
| 1016 | mlx4_cleanup_counters_table(dev); | ||
| 1017 | |||
| 972 | err_qp_table_free: | 1018 | err_qp_table_free: |
| 973 | mlx4_cleanup_qp_table(dev); | 1019 | mlx4_cleanup_qp_table(dev); |
| 974 | 1020 | ||
| @@ -1299,6 +1345,7 @@ err_port: | |||
| 1299 | for (--port; port >= 1; --port) | 1345 | for (--port; port >= 1; --port) |
| 1300 | mlx4_cleanup_port_info(&priv->port[port]); | 1346 | mlx4_cleanup_port_info(&priv->port[port]); |
| 1301 | 1347 | ||
| 1348 | mlx4_cleanup_counters_table(dev); | ||
| 1302 | mlx4_cleanup_mcg_table(dev); | 1349 | mlx4_cleanup_mcg_table(dev); |
| 1303 | mlx4_cleanup_qp_table(dev); | 1350 | mlx4_cleanup_qp_table(dev); |
| 1304 | mlx4_cleanup_srq_table(dev); | 1351 | mlx4_cleanup_srq_table(dev); |
| @@ -1359,6 +1406,7 @@ static void mlx4_remove_one(struct pci_dev *pdev) | |||
| 1359 | mlx4_CLOSE_PORT(dev, p); | 1406 | mlx4_CLOSE_PORT(dev, p); |
| 1360 | } | 1407 | } |
| 1361 | 1408 | ||
| 1409 | mlx4_cleanup_counters_table(dev); | ||
| 1362 | mlx4_cleanup_mcg_table(dev); | 1410 | mlx4_cleanup_mcg_table(dev); |
| 1363 | mlx4_cleanup_qp_table(dev); | 1411 | mlx4_cleanup_qp_table(dev); |
| 1364 | mlx4_cleanup_srq_table(dev); | 1412 | mlx4_cleanup_srq_table(dev); |
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c index e63c37d6a11..cd1784593a3 100644 --- a/drivers/net/mlx4/mcg.c +++ b/drivers/net/mlx4/mcg.c | |||
| @@ -559,7 +559,8 @@ static int find_entry(struct mlx4_dev *dev, u8 port, | |||
| 559 | struct mlx4_mgm *mgm = mgm_mailbox->buf; | 559 | struct mlx4_mgm *mgm = mgm_mailbox->buf; |
| 560 | u8 *mgid; | 560 | u8 *mgid; |
| 561 | int err; | 561 | int err; |
| 562 | u8 op_mod = (prot == MLX4_PROT_ETH) ? !!(dev->caps.vep_mc_steering) : 0; | 562 | u8 op_mod = (prot == MLX4_PROT_ETH) ? |
| 563 | !!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) : 0; | ||
| 563 | 564 | ||
| 564 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 565 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
| 565 | if (IS_ERR(mailbox)) | 566 | if (IS_ERR(mailbox)) |
| @@ -834,7 +835,8 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], | |||
| 834 | 835 | ||
| 835 | steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER; | 836 | steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER; |
| 836 | 837 | ||
| 837 | if (prot == MLX4_PROT_ETH && !dev->caps.vep_mc_steering) | 838 | if (prot == MLX4_PROT_ETH && |
| 839 | !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) | ||
| 838 | return 0; | 840 | return 0; |
| 839 | 841 | ||
| 840 | if (prot == MLX4_PROT_ETH) | 842 | if (prot == MLX4_PROT_ETH) |
| @@ -853,7 +855,8 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], | |||
| 853 | 855 | ||
| 854 | steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER; | 856 | steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER; |
| 855 | 857 | ||
| 856 | if (prot == MLX4_PROT_ETH && !dev->caps.vep_mc_steering) | 858 | if (prot == MLX4_PROT_ETH && |
| 859 | !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) | ||
| 857 | return 0; | 860 | return 0; |
| 858 | 861 | ||
| 859 | if (prot == MLX4_PROT_ETH) { | 862 | if (prot == MLX4_PROT_ETH) { |
| @@ -867,7 +870,7 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_detach); | |||
| 867 | 870 | ||
| 868 | int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) | 871 | int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) |
| 869 | { | 872 | { |
| 870 | if (!dev->caps.vep_mc_steering) | 873 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) |
| 871 | return 0; | 874 | return 0; |
| 872 | 875 | ||
| 873 | 876 | ||
| @@ -877,7 +880,7 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add); | |||
| 877 | 880 | ||
| 878 | int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) | 881 | int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) |
| 879 | { | 882 | { |
| 880 | if (!dev->caps.vep_mc_steering) | 883 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) |
| 881 | return 0; | 884 | return 0; |
| 882 | 885 | ||
| 883 | 886 | ||
| @@ -887,7 +890,7 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove); | |||
| 887 | 890 | ||
| 888 | int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) | 891 | int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) |
| 889 | { | 892 | { |
| 890 | if (!dev->caps.vep_mc_steering) | 893 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) |
| 891 | return 0; | 894 | return 0; |
| 892 | 895 | ||
| 893 | 896 | ||
| @@ -897,7 +900,7 @@ EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add); | |||
| 897 | 900 | ||
| 898 | int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) | 901 | int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) |
| 899 | { | 902 | { |
| 900 | if (!dev->caps.vep_mc_steering) | 903 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) |
| 901 | return 0; | 904 | return 0; |
| 902 | 905 | ||
| 903 | return remove_promisc_qp(dev, 0, port, MLX4_UC_STEER, qpn); | 906 | return remove_promisc_qp(dev, 0, port, MLX4_UC_STEER, qpn); |
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index dd7d745fbab..a2fcd8402d3 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h | |||
| @@ -48,8 +48,8 @@ | |||
| 48 | #include <linux/mlx4/doorbell.h> | 48 | #include <linux/mlx4/doorbell.h> |
| 49 | 49 | ||
| 50 | #define DRV_NAME "mlx4_core" | 50 | #define DRV_NAME "mlx4_core" |
| 51 | #define DRV_VERSION "0.01" | 51 | #define DRV_VERSION "1.0" |
| 52 | #define DRV_RELDATE "May 1, 2007" | 52 | #define DRV_RELDATE "July 14, 2011" |
| 53 | 53 | ||
| 54 | enum { | 54 | enum { |
| 55 | MLX4_HCR_BASE = 0x80680, | 55 | MLX4_HCR_BASE = 0x80680, |
| @@ -342,6 +342,7 @@ struct mlx4_priv { | |||
| 342 | struct mlx4_srq_table srq_table; | 342 | struct mlx4_srq_table srq_table; |
| 343 | struct mlx4_qp_table qp_table; | 343 | struct mlx4_qp_table qp_table; |
| 344 | struct mlx4_mcg_table mcg_table; | 344 | struct mlx4_mcg_table mcg_table; |
| 345 | struct mlx4_bitmap counters_bitmap; | ||
| 345 | 346 | ||
| 346 | struct mlx4_catas_err catas_err; | 347 | struct mlx4_catas_err catas_err; |
| 347 | 348 | ||
diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c index 8856659fb43..1f95afda684 100644 --- a/drivers/net/mlx4/port.c +++ b/drivers/net/mlx4/port.c | |||
| @@ -146,7 +146,7 @@ int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn, u8 wrap) | |||
| 146 | int i, err = 0; | 146 | int i, err = 0; |
| 147 | int free = -1; | 147 | int free = -1; |
| 148 | 148 | ||
| 149 | if (dev->caps.vep_uc_steering) { | 149 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { |
| 150 | err = mlx4_uc_steer_add(dev, port, mac, qpn, 1); | 150 | err = mlx4_uc_steer_add(dev, port, mac, qpn, 1); |
| 151 | if (!err) { | 151 | if (!err) { |
| 152 | entry = kmalloc(sizeof *entry, GFP_KERNEL); | 152 | entry = kmalloc(sizeof *entry, GFP_KERNEL); |
| @@ -203,7 +203,7 @@ int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn, u8 wrap) | |||
| 203 | goto out; | 203 | goto out; |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | if (!dev->caps.vep_uc_steering) | 206 | if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) |
| 207 | *qpn = info->base_qpn + free; | 207 | *qpn = info->base_qpn + free; |
| 208 | ++table->total; | 208 | ++table->total; |
| 209 | out: | 209 | out: |
| @@ -243,7 +243,7 @@ void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int qpn) | |||
| 243 | int index = qpn - info->base_qpn; | 243 | int index = qpn - info->base_qpn; |
| 244 | struct mlx4_mac_entry *entry; | 244 | struct mlx4_mac_entry *entry; |
| 245 | 245 | ||
| 246 | if (dev->caps.vep_uc_steering) { | 246 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { |
| 247 | entry = radix_tree_lookup(&info->mac_tree, qpn); | 247 | entry = radix_tree_lookup(&info->mac_tree, qpn); |
| 248 | if (entry) { | 248 | if (entry) { |
| 249 | mlx4_uc_steer_release(dev, port, entry->mac, qpn, 1); | 249 | mlx4_uc_steer_release(dev, port, entry->mac, qpn, 1); |
| @@ -274,7 +274,7 @@ int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac, u8 wra | |||
| 274 | struct mlx4_mac_entry *entry; | 274 | struct mlx4_mac_entry *entry; |
| 275 | int err; | 275 | int err; |
| 276 | 276 | ||
| 277 | if (dev->caps.vep_uc_steering) { | 277 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) { |
| 278 | entry = radix_tree_lookup(&info->mac_tree, qpn); | 278 | entry = radix_tree_lookup(&info->mac_tree, qpn); |
| 279 | if (!entry) | 279 | if (!entry) |
| 280 | return -EINVAL; | 280 | return -EINVAL; |
