From: Knut Omang Date: Tue, 20 Sep 2016 07:26:59 +0000 (+0200) Subject: sif: qp: Clear the QP state cq_int_err bit upon reset X-Git-Tag: v4.1.12-92~67^2~26 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=46eac6aae1f0799531ff25be87e8686346064776;p=users%2Fjedix%2Flinux-maple.git sif: qp: Clear the QP state cq_int_err bit upon reset 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 Reviewed-by: HÃ¥kon Bugge --- diff --git a/drivers/infiniband/hw/sif/psif_hw_macro.h b/drivers/infiniband/hw/sif/psif_hw_macro.h index 57f09def4cad..ff529315deff 100644 --- a/drivers/infiniband/hw/sif/psif_hw_macro.h +++ b/drivers/infiniband/hw/sif/psif_hw_macro.h @@ -171,6 +171,14 @@ #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 diff --git a/drivers/infiniband/hw/sif/psif_hw_setget.h b/drivers/infiniband/hw/sif/psif_hw_setget.h index 957ba2fb169d..88beafc6eaf7 100644 --- a/drivers/infiniband/hw/sif/psif_hw_setget.h +++ b/drivers/infiniband/hw/sif/psif_hw_setget.h @@ -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, diff --git a/drivers/infiniband/hw/sif/sif_qp.c b/drivers/infiniband/hw/sif/sif_qp.c index ee843e469bb0..feb4f3150350 100644 --- a/drivers/infiniband/hw/sif/sif_qp.c +++ b/drivers/infiniband/hw/sif/sif_qp.c @@ -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; }