aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx4/main.c
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2012-01-11 12:00:29 -0500
committerRoland Dreier <roland@purestorage.com>2012-03-12 19:24:59 -0400
commita9c766bb75ee2caad2735e41784387784ffd87db (patch)
tree8dbc6a8fe8e2b6853f817b029d34dbcf856d0684 /drivers/infiniband/hw/mlx4/main.c
parent3616f9cead935d4e4c35915600d5e4d1384219cd (diff)
IB/mlx4: Fix info returned when querying IBoE ports
To issue a port query, use the QUERY_(Ethernet)_PORT command instead of the MAD_IFC command, since MAD_IFC attempts to query the firmware IB SMA, which is irrelevant for IBoE ports. This allows us to handle both 10Gb/s and 40Gb/s rates (e.g in sysfs), using QDR speed (10Gb/s) and width of 1X or 4X. Signed-off-by: Dotan Barak <dotanb@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/mlx4/main.c')
-rw-r--r--drivers/infiniband/hw/mlx4/main.c97
1 files changed, 53 insertions, 44 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index e152837b75a5..1349cb1b597a 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -182,12 +182,27 @@ mlx4_ib_port_link_layer(struct ib_device *device, u8 port_num)
182} 182}
183 183
184static int ib_link_query_port(struct ib_device *ibdev, u8 port, 184static int ib_link_query_port(struct ib_device *ibdev, u8 port,
185 struct ib_port_attr *props, 185 struct ib_port_attr *props)
186 struct ib_smp *in_mad,
187 struct ib_smp *out_mad)
188{ 186{
187 struct ib_smp *in_mad = NULL;
188 struct ib_smp *out_mad = NULL;
189 int ext_active_speed; 189 int ext_active_speed;
190 int err; 190 int err = -ENOMEM;
191
192 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
193 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
194 if (!in_mad || !out_mad)
195 goto out;
196
197 init_query_mad(in_mad);
198 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
199 in_mad->attr_mod = cpu_to_be32(port);
200
201 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL,
202 in_mad, out_mad);
203 if (err)
204 goto out;
205
191 206
192 props->lid = be16_to_cpup((__be16 *) (out_mad->data + 16)); 207 props->lid = be16_to_cpup((__be16 *) (out_mad->data + 16));
193 props->lmc = out_mad->data[34] & 0x7; 208 props->lmc = out_mad->data[34] & 0x7;
@@ -234,15 +249,17 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,
234 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, 249 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port,
235 NULL, NULL, in_mad, out_mad); 250 NULL, NULL, in_mad, out_mad);
236 if (err) 251 if (err)
237 return err; 252 goto out;
238 253
239 /* Checking LinkSpeedActive for FDR-10 */ 254 /* Checking LinkSpeedActive for FDR-10 */
240 if (out_mad->data[15] & 0x1) 255 if (out_mad->data[15] & 0x1)
241 props->active_speed = 8; 256 props->active_speed = 8;
242 } 257 }
243 } 258 }
244 259out:
245 return 0; 260 kfree(in_mad);
261 kfree(out_mad);
262 return err;
246} 263}
247 264
248static u8 state_to_phys_state(enum ib_port_state state) 265static u8 state_to_phys_state(enum ib_port_state state)
@@ -251,32 +268,42 @@ static u8 state_to_phys_state(enum ib_port_state state)
251} 268}
252 269
253static int eth_link_query_port(struct ib_device *ibdev, u8 port, 270static int eth_link_query_port(struct ib_device *ibdev, u8 port,
254 struct ib_port_attr *props, 271 struct ib_port_attr *props)
255 struct ib_smp *out_mad)
256{ 272{
257 struct mlx4_ib_iboe *iboe = &to_mdev(ibdev)->iboe; 273
274 struct mlx4_ib_dev *mdev = to_mdev(ibdev);
275 struct mlx4_ib_iboe *iboe = &mdev->iboe;
258 struct net_device *ndev; 276 struct net_device *ndev;
259 enum ib_mtu tmp; 277 enum ib_mtu tmp;
278 struct mlx4_cmd_mailbox *mailbox;
279 int err = 0;
280
281 mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
282 if (IS_ERR(mailbox))
283 return PTR_ERR(mailbox);
284
285 err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, port, 0,
286 MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B,
287 MLX4_CMD_WRAPPED);
288 if (err)
289 goto out;
260 290
261 props->active_width = IB_WIDTH_1X; 291 props->active_width = (((u8 *)mailbox->buf)[5] == 0x40) ?
292 IB_WIDTH_4X : IB_WIDTH_1X;
262 props->active_speed = 4; 293 props->active_speed = 4;
263 props->port_cap_flags = IB_PORT_CM_SUP; 294 props->port_cap_flags = IB_PORT_CM_SUP;
264 props->gid_tbl_len = to_mdev(ibdev)->dev->caps.gid_table_len[port]; 295 props->gid_tbl_len = mdev->dev->caps.gid_table_len[port];
265 props->max_msg_sz = to_mdev(ibdev)->dev->caps.max_msg_sz; 296 props->max_msg_sz = mdev->dev->caps.max_msg_sz;
266 props->pkey_tbl_len = 1; 297 props->pkey_tbl_len = 1;
267 props->bad_pkey_cntr = be16_to_cpup((__be16 *) (out_mad->data + 46));
268 props->qkey_viol_cntr = be16_to_cpup((__be16 *) (out_mad->data + 48));
269 props->max_mtu = IB_MTU_4096; 298 props->max_mtu = IB_MTU_4096;
270 props->subnet_timeout = 0; 299 props->max_vl_num = 2;
271 props->max_vl_num = out_mad->data[37] >> 4;
272 props->init_type_reply = 0;
273 props->state = IB_PORT_DOWN; 300 props->state = IB_PORT_DOWN;
274 props->phys_state = state_to_phys_state(props->state); 301 props->phys_state = state_to_phys_state(props->state);
275 props->active_mtu = IB_MTU_256; 302 props->active_mtu = IB_MTU_256;
276 spin_lock(&iboe->lock); 303 spin_lock(&iboe->lock);
277 ndev = iboe->netdevs[port - 1]; 304 ndev = iboe->netdevs[port - 1];
278 if (!ndev) 305 if (!ndev)
279 goto out; 306 goto out_unlock;
280 307
281 tmp = iboe_get_mtu(ndev->mtu); 308 tmp = iboe_get_mtu(ndev->mtu);
282 props->active_mtu = tmp ? min(props->max_mtu, tmp) : IB_MTU_256; 309 props->active_mtu = tmp ? min(props->max_mtu, tmp) : IB_MTU_256;
@@ -284,41 +311,23 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
284 props->state = (netif_running(ndev) && netif_carrier_ok(ndev)) ? 311 props->state = (netif_running(ndev) && netif_carrier_ok(ndev)) ?
285 IB_PORT_ACTIVE : IB_PORT_DOWN; 312 IB_PORT_ACTIVE : IB_PORT_DOWN;
286 props->phys_state = state_to_phys_state(props->state); 313 props->phys_state = state_to_phys_state(props->state);
287 314out_unlock:
288out:
289 spin_unlock(&iboe->lock); 315 spin_unlock(&iboe->lock);
290 return 0; 316out:
317 mlx4_free_cmd_mailbox(mdev->dev, mailbox);
318 return err;
291} 319}
292 320
293static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port, 321static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
294 struct ib_port_attr *props) 322 struct ib_port_attr *props)
295{ 323{
296 struct ib_smp *in_mad = NULL; 324 int err;
297 struct ib_smp *out_mad = NULL;
298 int err = -ENOMEM;
299
300 in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
301 out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
302 if (!in_mad || !out_mad)
303 goto out;
304 325
305 memset(props, 0, sizeof *props); 326 memset(props, 0, sizeof *props);
306 327
307 init_query_mad(in_mad);
308 in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
309 in_mad->attr_mod = cpu_to_be32(port);
310
311 err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad);
312 if (err)
313 goto out;
314
315 err = mlx4_ib_port_link_layer(ibdev, port) == IB_LINK_LAYER_INFINIBAND ? 328 err = mlx4_ib_port_link_layer(ibdev, port) == IB_LINK_LAYER_INFINIBAND ?
316 ib_link_query_port(ibdev, port, props, in_mad, out_mad) : 329 ib_link_query_port(ibdev, port, props) :
317 eth_link_query_port(ibdev, port, props, out_mad); 330 eth_link_query_port(ibdev, port, props);
318
319out:
320 kfree(in_mad);
321 kfree(out_mad);
322 331
323 return err; 332 return err;
324} 333}