IB/mlx4: Configure extended active speeds
authorMarcel Apfelbaum <marcela@dev.mellanox.co.il>
Mon, 3 Oct 2011 16:04:20 +0000 (19:04 +0300)
committerRoland Dreier <roland@purestorage.com>
Fri, 28 Oct 2011 18:36:16 +0000 (11:36 -0700)
Set the extended active speeds based on the hardware configuration.

Signed-off-by: Marcel Apfelbaum <marcela@dev.mellanox.co.il>
Reviewed-by: Hal Rosenstock <hal@mellanox.com>
[ Move FDR-10 handling into ib_link_query_port().  - Roland ]

Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/mlx4/main.c

index fa643f4..4e5b654 100644 (file)
@@ -181,8 +181,12 @@ mlx4_ib_port_link_layer(struct ib_device *device, u8 port_num)
 
 static int ib_link_query_port(struct ib_device *ibdev, u8 port,
                              struct ib_port_attr *props,
+                             struct ib_smp *in_mad,
                              struct ib_smp *out_mad)
 {
+       int ext_active_speed;
+       int err;
+
        props->lid              = be16_to_cpup((__be16 *) (out_mad->data + 16));
        props->lmc              = out_mad->data[34] & 0x7;
        props->sm_lid           = be16_to_cpup((__be16 *) (out_mad->data + 18));
@@ -203,6 +207,39 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,
        props->max_vl_num       = out_mad->data[37] >> 4;
        props->init_type_reply  = out_mad->data[41] >> 4;
 
+       /* Check if extended speeds (EDR/FDR/...) are supported */
+       if (props->port_cap_flags & IB_PORT_EXTENDED_SPEEDS_SUP) {
+               ext_active_speed = out_mad->data[62] >> 4;
+
+               switch (ext_active_speed) {
+               case 1:
+                       props->active_speed = 16; /* FDR */
+                       break;
+               case 2:
+                       props->active_speed = 32; /* EDR */
+                       break;
+               }
+       }
+
+       /* If reported active speed is QDR, check if is FDR-10 */
+       if (props->active_speed == 4) {
+               if (to_mdev(ibdev)->dev->caps.ext_port_cap[port] &
+                   MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO) {
+                       init_query_mad(in_mad);
+                       in_mad->attr_id = MLX4_ATTR_EXTENDED_PORT_INFO;
+                       in_mad->attr_mod = cpu_to_be32(port);
+
+                       err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port,
+                                          NULL, NULL, in_mad, out_mad);
+                       if (err)
+                               return err;
+
+                       /* Checking LinkSpeedActive for FDR-10 */
+                       if (out_mad->data[15] & 0x1)
+                               props->active_speed = 8;
+               }
+       }
+
        return 0;
 }
 
@@ -274,7 +311,7 @@ static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
                goto out;
 
        err = mlx4_ib_port_link_layer(ibdev, port) == IB_LINK_LAYER_INFINIBAND ?
-               ib_link_query_port(ibdev, port, props, out_mad) :
+               ib_link_query_port(ibdev, port, props, in_mad, out_mad) :
                eth_link_query_port(ibdev, port, props, out_mad);
 
 out: