]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sif: qp: Clear the QP state cq_int_err bit upon reset
authorKnut Omang <knut.omang@oracle.com>
Tue, 20 Sep 2016 07:26:59 +0000 (09:26 +0200)
committerKnut Omang <knut.omang@oracle.com>
Mon, 3 Oct 2016 12:02:24 +0000 (14:02 +0200)
During reset of a QP, the cq_int_err bit was not reset.
This would cause a subsequent transition to RTR to fail
and hardware to set the QP back in error again.

Orabug: 24708282

Signed-off-by: Knut Omang <knut.omang@oracle.com>
Reviewed-by: HÃ¥kon Bugge <haakon.bugge@oracle.com>
drivers/infiniband/hw/sif/psif_hw_macro.h
drivers/infiniband/hw/sif/psif_hw_setget.h
drivers/infiniband/hw/sif/sif_qp.c

index 57f09def4cad130341384b082689530032c7d774..ff529315deff1721f1d6d2874d390000886527ed 100644 (file)
 #define PSIF_QP_CORE_ERROR_RETRY_COUNT_BITS    3
 #define PSIF_QP_CORE_ERROR_RETRY_COUNT_MASK    0x0000003800000000ull
 
+/*
+ * When 1, indicates that the receive queue of this QP is a shared receive
+ * queue. This bit is used by tsu_err to classify errors.
+ */
+#define PSIF_QP_CORE_CQ_IN_ERR_OFFSET  0
+#define PSIF_QP_CORE_CQ_IN_ERR_BIT_POSITION            38
+#define PSIF_QP_CORE_CQ_IN_ERR_BIT     0x0000004000000000ull
+
 /* A hit in the set locally spun out of tsu_cmpl is found. */
 #define PSIF_QP_CORE_SPIN_HIT_OFFSET   0
 #define PSIF_QP_CORE_SPIN_HIT_BIT_POSITION             39
index 957ba2fb169d48b3704b3ae479efa53fa4c51535..88beafc6eaf7ebb95f195e26b3d86d4ff731fc8f 100644 (file)
@@ -369,6 +369,26 @@ static inline u8 get_psif_qp_core__error_retry_count(volatile struct psif_qp_cor
        return((u8)((be64_to_cpu(pte[0]) >> 35) & 0x0000000000000007ull));
 }
 
+/*
+ * When 1, indicates that the receive queue of this QP is a shared receive
+ * queue. This bit is used by tsu_err to classify errors.
+ */
+static inline void set_psif_qp_core__cq_in_err(
+       volatile struct psif_qp_core *ptr,
+       u8 data)
+{
+       /* group=0 shift=38 bits=1 */
+       volatile __be64 *const pte = (__be64 *)ptr;
+       pte[0] = cpu_to_be64((be64_to_cpu(pte[0]) & 0xffffffbfffffffffull) |
+               ((((u64)(data)) & 0x0000000000000001ull) << 38));
+}
+static inline u8 get_psif_qp_core__cq_in_err(volatile struct psif_qp_core *ptr)
+{
+       /* group=0 shift=38 bits=1 */
+       volatile __be64 *const pte = (__be64 *)ptr;
+       return((u8)((be64_to_cpu(pte[0]) >> 38) & 0x0000000000000001ull));
+}
+
 /* A hit in the set locally spun out of tsu_cmpl is found. */
 static inline void set_psif_qp_core__spin_hit(
        volatile struct psif_qp_core *ptr,
index ee843e469bb04a8065f1076b55ec205b075fe1aa..feb4f31503506d2a06d246f2702048411c4d3ff4 100644 (file)
@@ -412,7 +412,7 @@ struct sif_qp *create_qp(struct sif_dev *sdev,
        qpi.state.mstate = APM_MIGRATED;
        qpi.state.path_mtu = ib2sif_path_mtu(qp->mtu);
        /* Last acked psn must be initialized to one less than xmit_psn
-        * and it is a 24 bit value. See issue #1011
+        * and it is a 24 bit value. See bug #1011
         */
        qpi.state.xmit_psn = 0;
        qpi.state.last_acked_psn = 0xffffff;
@@ -1860,18 +1860,23 @@ int sif_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
 
 }
 
-static void get_qp_path_sw(struct sif_qp *qp, struct ib_qp_attr *qp_attr)
+static void get_qp_path_sw(struct sif_qp *qp, struct ib_qp_attr *qp_attr, bool alternate)
 {
        volatile struct psif_qp_path *path;
        struct ib_ah_attr *ah_attr;
+       enum psif_use_grh use_grh;
        volatile struct psif_qp_path *alt_path;
        struct ib_ah_attr *alt_ah_attr;
 
+       alt_path =  &qp->d.path_b;
+       alt_ah_attr = &qp_attr->alt_ah_attr;
        path = &qp->d.path_a;
        ah_attr = &qp_attr->ah_attr;
+
        ah_attr->sl = get_psif_qp_path__sl(path);
+       use_grh = get_psif_qp_path__use_grh(path);
 
-       if (get_psif_qp_path__use_grh(path) == USE_GRH) {
+       if (use_grh == USE_GRH) {
                ah_attr->ah_flags |= IB_AH_GRH;
                ah_attr->grh.dgid.global.subnet_prefix = get_psif_qp_path__remote_gid_0(path);
                ah_attr->grh.dgid.global.interface_id = get_psif_qp_path__remote_gid_1(path);
@@ -1887,22 +1892,6 @@ static void get_qp_path_sw(struct sif_qp *qp, struct ib_qp_attr *qp_attr)
        ah_attr->dlid = get_psif_qp_path__remote_lid(path);
        ah_attr->src_path_bits = get_psif_qp_path__local_lid_path(path);
 
-       alt_path =  &qp->d.path_b;
-       alt_ah_attr = &qp_attr->alt_ah_attr;
-       alt_ah_attr->sl = get_psif_qp_path__sl(alt_path);
-
-       if (get_psif_qp_path__use_grh(alt_path) == USE_GRH) {
-               alt_ah_attr->ah_flags |= IB_AH_GRH;
-               alt_ah_attr->grh.dgid.global.subnet_prefix = get_psif_qp_path__remote_gid_0(alt_path);
-               alt_ah_attr->grh.dgid.global.interface_id = get_psif_qp_path__remote_gid_1(alt_path);
-               alt_ah_attr->grh.flow_label = get_psif_qp_path__flowlabel(alt_path);
-               alt_ah_attr->grh.hop_limit = get_psif_qp_path__hoplmt(alt_path);
-               /* TBD: ah_attr->grh.sgid_index? */
-       }
-
-       qp_attr->alt_pkey_index = get_psif_qp_path__pkey_indx(alt_path);
-       qp_attr->alt_timeout = get_psif_qp_path__local_ack_timeout(alt_path);
-
        alt_ah_attr->port_num = get_psif_qp_path__port(alt_path);
        alt_ah_attr->dlid =     get_psif_qp_path__remote_lid(alt_path);
        alt_ah_attr->src_path_bits = get_psif_qp_path__local_lid_path(alt_path);
@@ -1943,7 +1932,7 @@ static int sif_query_qp_sw(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
        qp_attr->pkey_index = get_psif_qp_path__pkey_indx(&qps->path_a);
        qp_attr->port_num = qp->port;
        qp_attr->qkey = get_psif_qp_core__qkey(&qps->state);
-       get_qp_path_sw(qp, qp_attr);
+       get_qp_path_sw(qp, qp_attr, qp_attr_mask & IB_QP_ALT_PATH);
 
        qp_attr->path_mtu = sif2ib_path_mtu(get_psif_qp_core__path_mtu(&qps->state));
        qp_attr->timeout = get_psif_qp_path__local_ack_timeout(&qps->path_a);
@@ -1971,23 +1960,30 @@ static int sif_query_qp_sw(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
                qp_init_attr->cap.max_send_sge    = sq->sg_entries;
        }
        qp_init_attr->cap.max_inline_data = qp->max_inline_data;
-       qp_attr->max_rd_atomic = get_psif_qp_core__max_outstanding(&qps->state);
 
+       /* TBD: What to do with this:
+        * IB_QP_MAX_QP_RD_ATOMIC               = (1<<13),
+        */
        return ret;
 }
 
-static void get_qp_path_hw(struct psif_query_qp *qqp, struct ib_qp_attr *qp_attr)
+static void get_qp_path_hw(struct psif_query_qp *qqp, struct ib_qp_attr *qp_attr, bool alternate)
 {
        struct psif_qp_path *path;
        struct ib_ah_attr *ah_attr;
+       enum psif_use_grh use_grh;
        struct psif_qp_path *alt_path;
        struct ib_ah_attr *alt_ah_attr;
 
+       alt_path =  &qqp->alternate_path;
+       alt_ah_attr = &qp_attr->alt_ah_attr;
        path = &qqp->primary_path;
        ah_attr = &qp_attr->ah_attr;
+
        ah_attr->sl = path->sl;
+       use_grh = path->use_grh;
 
-       if (path->use_grh == USE_GRH) {
+       if (use_grh == USE_GRH) {
                ah_attr->ah_flags |= IB_AH_GRH;
                ah_attr->grh.dgid.global.subnet_prefix = path->remote_gid_0;
                ah_attr->grh.dgid.global.interface_id = path->remote_gid_1;
@@ -1995,34 +1991,23 @@ static void get_qp_path_hw(struct psif_query_qp *qqp, struct ib_qp_attr *qp_attr
                ah_attr->grh.hop_limit = path->hoplmt;
                /* TBD: ah_attr->grh.sgid_index? */
        }
+       qp_attr->pkey_index = path->pkey_indx;
+       qp_attr->timeout = path->local_ack_timeout;
+       qp_attr->port_num = path->port + 1;
+
+       qp_attr->alt_pkey_index = alt_path->pkey_indx;
+       qp_attr->alt_timeout = alt_path->local_ack_timeout;
+       qp_attr->alt_port_num = alt_path->port + 1;
+
+
 
        ah_attr->port_num = path->port + 1;
        ah_attr->dlid = path->remote_lid;
        ah_attr->src_path_bits = path->local_lid_path;
 
-       qp_attr->pkey_index = path->pkey_indx;
-       qp_attr->timeout = path->local_ack_timeout;
-       qp_attr->port_num = path->port + 1;
-
-       alt_path =  &qqp->alternate_path;
-       alt_ah_attr = &qp_attr->alt_ah_attr;
-       alt_ah_attr->sl = alt_path->sl;
-
-       if (alt_path->use_grh == USE_GRH) {
-               alt_ah_attr->ah_flags |= IB_AH_GRH;
-               alt_ah_attr->grh.dgid.global.subnet_prefix = alt_path->remote_gid_0;
-               alt_ah_attr->grh.dgid.global.interface_id = alt_path->remote_gid_1;
-               alt_ah_attr->grh.flow_label = alt_path->flowlabel;
-               alt_ah_attr->grh.hop_limit = alt_path->hoplmt;
-               /* TBD: ah_attr->grh.sgid_index? */
-       }
        alt_ah_attr->port_num = alt_path->port + 1;
        alt_ah_attr->dlid =     alt_path->remote_lid;
        alt_ah_attr->src_path_bits = alt_path->local_lid_path;
-
-       qp_attr->alt_pkey_index = alt_path->pkey_indx;
-       qp_attr->alt_timeout = alt_path->local_ack_timeout;
-       qp_attr->alt_port_num = alt_path->port + 1;
 }
 
 u64 sif_qqp_dma_addr(struct sif_dev *sdev, struct sif_qp *qps)
@@ -2117,7 +2102,7 @@ static int sif_query_qp_hw(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
        qp_attr->pkey_index = lqqp.primary_path.pkey_indx;
        qp_attr->port_num = lqqp.primary_path.port + 1;
        qp_attr->qkey = lqqp.qp.qkey;
-       get_qp_path_hw(&lqqp, qp_attr);
+       get_qp_path_hw(&lqqp, qp_attr, qp_attr_mask & IB_QP_ALT_PATH);
 
        qp_attr->path_mtu = sif2ib_path_mtu(lqqp.qp.path_mtu);
        qp_attr->timeout = lqqp.primary_path.local_ack_timeout;
@@ -2146,8 +2131,10 @@ static int sif_query_qp_hw(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
                qp_init_attr->cap.max_send_sge    = sq->sg_entries;
        }
        qp_init_attr->cap.max_inline_data = qp->max_inline_data;
-       qp_attr->max_rd_atomic = lqqp.qp.max_outstanding;
 
+       /* TBD: What to do with these..
+        * IB_QP_MAX_QP_RD_ATOMIC               = (1<<13),
+        */
        return ret;
 }
 
@@ -2414,6 +2401,7 @@ failed:
         */
        set_psif_qp_core__xmit_psn(&qps->state, 0);
        set_psif_qp_core__last_acked_psn(&qps->state, 0xffffff);
+       set_psif_qp_core__cq_in_err(&qps->state, 0);
 
        return ret;
 }