RDMA/ocrdma: Fix for displaying proper link speed
authorNaresh Gottumukkala <bgottumukkala@emulex.com>
Mon, 26 Aug 2013 09:57:47 +0000 (15:27 +0530)
committerRoland Dreier <roland@purestorage.com>
Tue, 3 Sep 2013 04:18:43 +0000 (21:18 -0700)
Signed-off-by: Naresh Gottumukkala <bgottumukkala@emulex.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/ocrdma/ocrdma_hw.c
drivers/infiniband/hw/ocrdma/ocrdma_hw.h
drivers/infiniband/hw/ocrdma/ocrdma_sli.h
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c

index 3f027552a1a13df1309b811dd8a8b78d0a2c5837..ea3d7237596a9b8acc9e350da21b28f7d2499e45 100644 (file)
@@ -1101,6 +1101,34 @@ mbx_err:
        return status;
 }
 
+int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed)
+{
+       int status = -ENOMEM;
+       struct ocrdma_get_link_speed_rsp *rsp;
+       struct ocrdma_mqe *cmd;
+
+       cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_NTWK_LINK_CONFIG_V1,
+                                 sizeof(*cmd));
+       if (!cmd)
+               return status;
+       ocrdma_init_mch((struct ocrdma_mbx_hdr *)&cmd->u.cmd[0],
+                       OCRDMA_CMD_QUERY_NTWK_LINK_CONFIG_V1,
+                       OCRDMA_SUBSYS_COMMON, sizeof(*cmd));
+
+       ((struct ocrdma_mbx_hdr *)cmd->u.cmd)->rsvd_version = 0x1;
+
+       status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
+       if (status)
+               goto mbx_err;
+
+       rsp = (struct ocrdma_get_link_speed_rsp *)cmd;
+       *lnk_speed = rsp->phys_port_speed;
+
+mbx_err:
+       kfree(cmd);
+       return status;
+}
+
 int ocrdma_mbx_alloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd)
 {
        int status = -ENOMEM;
index 044db74e780ab3c351c3baba1bb069880f3d9e8d..f2a89d4cc7c4b876808f1f8dacf25b96cf5ac00f 100644 (file)
@@ -91,6 +91,7 @@ void ocrdma_ring_cq_db(struct ocrdma_dev *, u16 cq_id, bool armed,
                       bool solicited, u16 cqe_popped);
 
 /* verbs specific mailbox commands */
+int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed);
 int ocrdma_query_config(struct ocrdma_dev *,
                        struct ocrdma_mbx_query_config *config);
 int ocrdma_resolve_dgid(struct ocrdma_dev *, union ib_gid *dgid, u8 *mac_addr);
index 35c61080ae1eaa6477f5a96004b79f86abc5c991..9e975d8884496aa61a84fe237cabaeb01726b1b0 100644 (file)
@@ -70,6 +70,7 @@ enum {
 
 #define OCRDMA_SUBSYS_COMMON 1
 enum {
+       OCRDMA_CMD_QUERY_NTWK_LINK_CONFIG_V1 = 5,
        OCRDMA_CMD_CREATE_CQ            = 12,
        OCRDMA_CMD_CREATE_EQ            = 13,
        OCRDMA_CMD_CREATE_MQ            = 21,
@@ -545,6 +546,32 @@ enum {
        OCRDMA_FN_MODE_RDMA     = 0x4
 };
 
+struct ocrdma_get_link_speed_rsp {
+       struct ocrdma_mqe_hdr hdr;
+       struct ocrdma_mbx_rsp rsp;
+
+       u8 pt_port_num;
+       u8 link_duplex;
+       u8 phys_port_speed;
+       u8 phys_port_fault;
+       u16 rsvd1;
+       u16 qos_lnk_speed;
+       u8 logical_lnk_status;
+       u8 rsvd2[3];
+};
+
+enum {
+       OCRDMA_PHYS_LINK_SPEED_ZERO = 0x0,
+       OCRDMA_PHYS_LINK_SPEED_10MBPS = 0x1,
+       OCRDMA_PHYS_LINK_SPEED_100MBPS = 0x2,
+       OCRDMA_PHYS_LINK_SPEED_1GBPS = 0x3,
+       OCRDMA_PHYS_LINK_SPEED_10GBPS = 0x4,
+       OCRDMA_PHYS_LINK_SPEED_20GBPS = 0x5,
+       OCRDMA_PHYS_LINK_SPEED_25GBPS = 0x6,
+       OCRDMA_PHYS_LINK_SPEED_40GBPS = 0x7,
+       OCRDMA_PHYS_LINK_SPEED_100GBPS = 0x8
+};
+
 enum {
        OCRDMA_CREATE_CQ_VER2                   = 2,
        OCRDMA_CREATE_CQ_VER3                   = 3,
index e934073e70524e8ab362a5789521e77265cf413d..f09a9403b6002d4dd69f54b62383f1db61833c51 100644 (file)
@@ -106,6 +106,45 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
        return 0;
 }
 
+static inline void get_link_speed_and_width(struct ocrdma_dev *dev,
+                                           u8 *ib_speed, u8 *ib_width)
+{
+       int status;
+       u8 speed;
+
+       status = ocrdma_mbx_get_link_speed(dev, &speed);
+       if (status)
+               speed = OCRDMA_PHYS_LINK_SPEED_ZERO;
+
+       switch (speed) {
+       case OCRDMA_PHYS_LINK_SPEED_1GBPS:
+               *ib_speed = IB_SPEED_SDR;
+               *ib_width = IB_WIDTH_1X;
+               break;
+
+       case OCRDMA_PHYS_LINK_SPEED_10GBPS:
+               *ib_speed = IB_SPEED_QDR;
+               *ib_width = IB_WIDTH_1X;
+               break;
+
+       case OCRDMA_PHYS_LINK_SPEED_20GBPS:
+               *ib_speed = IB_SPEED_DDR;
+               *ib_width = IB_WIDTH_4X;
+               break;
+
+       case OCRDMA_PHYS_LINK_SPEED_40GBPS:
+               *ib_speed = IB_SPEED_QDR;
+               *ib_width = IB_WIDTH_4X;
+               break;
+
+       default:
+               /* Unsupported */
+               *ib_speed = IB_SPEED_SDR;
+               *ib_width = IB_WIDTH_1X;
+       };
+}
+
+
 int ocrdma_query_port(struct ib_device *ibdev,
                      u8 port, struct ib_port_attr *props)
 {
@@ -142,8 +181,8 @@ int ocrdma_query_port(struct ib_device *ibdev,
        props->pkey_tbl_len = 1;
        props->bad_pkey_cntr = 0;
        props->qkey_viol_cntr = 0;
-       props->active_width = IB_WIDTH_1X;
-       props->active_speed = 4;
+       get_link_speed_and_width(dev, &props->active_speed,
+                                &props->active_width);
        props->max_msg_sz = 0x80000000;
        props->max_vl_num = 4;
        return 0;