aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 17:50:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 17:50:12 -0400
commitece236ce2fad9c27a6fd2530f899289025194bce (patch)
tree474b793205872206a2a3f7d409ff9b1f81f3a9a8 /drivers/net/mlx4
parent441c196e84b11aad3123baa9320eee7abc6b5c98 (diff)
parent4460207561290c3be7e6c7538f22690028170c1d (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.c9
-rw-r--r--drivers/net/mlx4/en_main.c3
-rw-r--r--drivers/net/mlx4/en_netdev.c5
-rw-r--r--drivers/net/mlx4/en_port.c6
-rw-r--r--drivers/net/mlx4/en_selftest.c3
-rw-r--r--drivers/net/mlx4/fw.c39
-rw-r--r--drivers/net/mlx4/fw.h8
-rw-r--r--drivers/net/mlx4/main.c58
-rw-r--r--drivers/net/mlx4/mcg.c17
-rw-r--r--drivers/net/mlx4/mlx4.h5
-rw-r--r--drivers/net/mlx4/port.c8
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
78static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 flags) 78static 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
121struct mlx4_adapter { 117struct 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
146static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) 147static 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
840static 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
852static void mlx4_cleanup_counters_table(struct mlx4_dev *dev)
853{
854 mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap);
855}
856
857int 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}
870EXPORT_SYMBOL_GPL(mlx4_counter_alloc);
871
872void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
873{
874 mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx);
875 return;
876}
877EXPORT_SYMBOL_GPL(mlx4_counter_free);
878
842static int mlx4_setup_hca(struct mlx4_dev *dev) 879static 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)
969err_mcg_table_free: 1012err_mcg_table_free:
970 mlx4_cleanup_mcg_table(dev); 1013 mlx4_cleanup_mcg_table(dev);
971 1014
1015err_counters_table_free:
1016 mlx4_cleanup_counters_table(dev);
1017
972err_qp_table_free: 1018err_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
868int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 871int 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
878int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 881int 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
888int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 891int 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
898int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 901int 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
54enum { 54enum {
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;
209out: 209out:
@@ -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;