mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	RDMA/qedr: Add iWARP support in existing verbs
Make slight modifications to common RoCE/iWARP code. Add additional doorbell for iWARP post_send. iWARP QP pbl is allocated in qed and not in qedr. Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com> Signed-off-by: Ram Amrani <Ram.Amrani@cavium.com> Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
		
							parent
							
								
									e6a38c54fa
								
							
						
					
					
						commit
						f5b1b1775b
					
				
					 2 changed files with 139 additions and 35 deletions
				
			
		| 
						 | 
					@ -319,6 +319,9 @@ struct qedr_qp_hwq_info {
 | 
				
			||||||
	/* DB */
 | 
						/* DB */
 | 
				
			||||||
	void __iomem *db;
 | 
						void __iomem *db;
 | 
				
			||||||
	union db_prod32 db_data;
 | 
						union db_prod32 db_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void __iomem *iwarp_db2;
 | 
				
			||||||
 | 
						union db_prod32 iwarp_db2_data;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QEDR_INC_SW_IDX(p_info, index)					\
 | 
					#define QEDR_INC_SW_IDX(p_info, index)					\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -277,8 +277,13 @@ int qedr_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *attr)
 | 
				
			||||||
	attr->sm_lid = 0;
 | 
						attr->sm_lid = 0;
 | 
				
			||||||
	attr->sm_sl = 0;
 | 
						attr->sm_sl = 0;
 | 
				
			||||||
	attr->port_cap_flags = IB_PORT_IP_BASED_GIDS;
 | 
						attr->port_cap_flags = IB_PORT_IP_BASED_GIDS;
 | 
				
			||||||
	attr->gid_tbl_len = QEDR_MAX_SGID;
 | 
						if (rdma_protocol_iwarp(&dev->ibdev, 1)) {
 | 
				
			||||||
	attr->pkey_tbl_len = QEDR_ROCE_PKEY_TABLE_LEN;
 | 
							attr->gid_tbl_len = 1;
 | 
				
			||||||
 | 
							attr->pkey_tbl_len = 1;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							attr->gid_tbl_len = QEDR_MAX_SGID;
 | 
				
			||||||
 | 
							attr->pkey_tbl_len = QEDR_ROCE_PKEY_TABLE_LEN;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	attr->bad_pkey_cntr = rdma_port->pkey_bad_counter;
 | 
						attr->bad_pkey_cntr = rdma_port->pkey_bad_counter;
 | 
				
			||||||
	attr->qkey_viol_cntr = 0;
 | 
						attr->qkey_viol_cntr = 0;
 | 
				
			||||||
	get_link_speed_and_width(rdma_port->link_speed,
 | 
						get_link_speed_and_width(rdma_port->link_speed,
 | 
				
			||||||
| 
						 | 
					@ -1430,6 +1435,21 @@ static int qedr_create_user_qp(struct qedr_dev *dev,
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void qedr_set_iwarp_db_info(struct qedr_dev *dev, struct qedr_qp *qp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						qp->sq.db = dev->db_addr +
 | 
				
			||||||
 | 
						    DB_ADDR_SHIFT(DQ_PWM_OFFSET_XCM_RDMA_SQ_PROD);
 | 
				
			||||||
 | 
						qp->sq.db_data.data.icid = qp->icid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qp->rq.db = dev->db_addr +
 | 
				
			||||||
 | 
							    DB_ADDR_SHIFT(DQ_PWM_OFFSET_TCM_IWARP_RQ_PROD);
 | 
				
			||||||
 | 
						qp->rq.db_data.data.icid = qp->icid;
 | 
				
			||||||
 | 
						qp->rq.iwarp_db2 = dev->db_addr +
 | 
				
			||||||
 | 
								   DB_ADDR_SHIFT(DQ_PWM_OFFSET_TCM_FLAGS);
 | 
				
			||||||
 | 
						qp->rq.iwarp_db2_data.data.icid = qp->icid;
 | 
				
			||||||
 | 
						qp->rq.iwarp_db2_data.data.value = DQ_TCM_IWARP_POST_RQ_CF_CMD;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
qedr_roce_create_kernel_qp(struct qedr_dev *dev,
 | 
					qedr_roce_create_kernel_qp(struct qedr_dev *dev,
 | 
				
			||||||
			   struct qedr_qp *qp,
 | 
								   struct qedr_qp *qp,
 | 
				
			||||||
| 
						 | 
					@ -1476,8 +1496,71 @@ qedr_roce_create_kernel_qp(struct qedr_dev *dev,
 | 
				
			||||||
	qp->icid = out_params.icid;
 | 
						qp->icid = out_params.icid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qedr_set_roce_db_info(dev, qp);
 | 
						qedr_set_roce_db_info(dev, qp);
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
					static int
 | 
				
			||||||
 | 
					qedr_iwarp_create_kernel_qp(struct qedr_dev *dev,
 | 
				
			||||||
 | 
								    struct qedr_qp *qp,
 | 
				
			||||||
 | 
								    struct qed_rdma_create_qp_in_params *in_params,
 | 
				
			||||||
 | 
								    u32 n_sq_elems, u32 n_rq_elems)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct qed_rdma_create_qp_out_params out_params;
 | 
				
			||||||
 | 
						struct qed_chain_ext_pbl ext_pbl;
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						in_params->sq_num_pages = QED_CHAIN_PAGE_CNT(n_sq_elems,
 | 
				
			||||||
 | 
											     QEDR_SQE_ELEMENT_SIZE,
 | 
				
			||||||
 | 
											     QED_CHAIN_MODE_PBL);
 | 
				
			||||||
 | 
						in_params->rq_num_pages = QED_CHAIN_PAGE_CNT(n_rq_elems,
 | 
				
			||||||
 | 
											     QEDR_RQE_ELEMENT_SIZE,
 | 
				
			||||||
 | 
											     QED_CHAIN_MODE_PBL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qp->qed_qp = dev->ops->rdma_create_qp(dev->rdma_ctx,
 | 
				
			||||||
 | 
										      in_params, &out_params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!qp->qed_qp)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Now we allocate the chain */
 | 
				
			||||||
 | 
						ext_pbl.p_pbl_virt = out_params.sq_pbl_virt;
 | 
				
			||||||
 | 
						ext_pbl.p_pbl_phys = out_params.sq_pbl_phys;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = dev->ops->common->chain_alloc(dev->cdev,
 | 
				
			||||||
 | 
										   QED_CHAIN_USE_TO_PRODUCE,
 | 
				
			||||||
 | 
										   QED_CHAIN_MODE_PBL,
 | 
				
			||||||
 | 
										   QED_CHAIN_CNT_TYPE_U32,
 | 
				
			||||||
 | 
										   n_sq_elems,
 | 
				
			||||||
 | 
										   QEDR_SQE_ELEMENT_SIZE,
 | 
				
			||||||
 | 
										   &qp->sq.pbl, &ext_pbl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rc)
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ext_pbl.p_pbl_virt = out_params.rq_pbl_virt;
 | 
				
			||||||
 | 
						ext_pbl.p_pbl_phys = out_params.rq_pbl_phys;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = dev->ops->common->chain_alloc(dev->cdev,
 | 
				
			||||||
 | 
										   QED_CHAIN_USE_TO_CONSUME_PRODUCE,
 | 
				
			||||||
 | 
										   QED_CHAIN_MODE_PBL,
 | 
				
			||||||
 | 
										   QED_CHAIN_CNT_TYPE_U32,
 | 
				
			||||||
 | 
										   n_rq_elems,
 | 
				
			||||||
 | 
										   QEDR_RQE_ELEMENT_SIZE,
 | 
				
			||||||
 | 
										   &qp->rq.pbl, &ext_pbl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rc)
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qp->qp_id = out_params.qp_id;
 | 
				
			||||||
 | 
						qp->icid = out_params.icid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qedr_set_iwarp_db_info(dev, qp);
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
						dev->ops->rdma_destroy_qp(dev->rdma_ctx, qp->qed_qp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void qedr_cleanup_kernel(struct qedr_dev *dev, struct qedr_qp *qp)
 | 
					static void qedr_cleanup_kernel(struct qedr_dev *dev, struct qedr_qp *qp)
 | 
				
			||||||
| 
						 | 
					@ -1552,8 +1635,12 @@ static int qedr_create_kernel_qp(struct qedr_dev *dev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	n_rq_elems = qp->rq.max_wr * QEDR_MAX_RQE_ELEMENTS_PER_RQE;
 | 
						n_rq_elems = qp->rq.max_wr * QEDR_MAX_RQE_ELEMENTS_PER_RQE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = qedr_roce_create_kernel_qp(dev, qp, &in_params,
 | 
						if (rdma_protocol_iwarp(&dev->ibdev, 1))
 | 
				
			||||||
					n_sq_elems, n_rq_elems);
 | 
							rc = qedr_iwarp_create_kernel_qp(dev, qp, &in_params,
 | 
				
			||||||
 | 
											 n_sq_elems, n_rq_elems);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							rc = qedr_roce_create_kernel_qp(dev, qp, &in_params,
 | 
				
			||||||
 | 
											n_sq_elems, n_rq_elems);
 | 
				
			||||||
	if (rc)
 | 
						if (rc)
 | 
				
			||||||
		qedr_cleanup_kernel(dev, qp);
 | 
							qedr_cleanup_kernel(dev, qp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1700,10 +1787,13 @@ static int qedr_update_qp_state(struct qedr_dev *dev,
 | 
				
			||||||
			/* Update doorbell (in case post_recv was
 | 
								/* Update doorbell (in case post_recv was
 | 
				
			||||||
			 * done before move to RTR)
 | 
								 * done before move to RTR)
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			wmb();
 | 
					
 | 
				
			||||||
			writel(qp->rq.db_data.raw, qp->rq.db);
 | 
								if (rdma_protocol_roce(&dev->ibdev, 1)) {
 | 
				
			||||||
			/* Make sure write takes effect */
 | 
									wmb();
 | 
				
			||||||
			mmiowb();
 | 
									writel(qp->rq.db_data.raw, qp->rq.db);
 | 
				
			||||||
 | 
									/* Make sure write takes effect */
 | 
				
			||||||
 | 
									mmiowb();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case QED_ROCE_QP_STATE_ERR:
 | 
							case QED_ROCE_QP_STATE_ERR:
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -1797,16 +1887,18 @@ int qedr_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		new_qp_state = old_qp_state;
 | 
							new_qp_state = old_qp_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ib_modify_qp_is_ok
 | 
						if (rdma_protocol_roce(&dev->ibdev, 1)) {
 | 
				
			||||||
	    (old_qp_state, new_qp_state, ibqp->qp_type, attr_mask,
 | 
							if (!ib_modify_qp_is_ok(old_qp_state, new_qp_state,
 | 
				
			||||||
	     IB_LINK_LAYER_ETHERNET)) {
 | 
										ibqp->qp_type, attr_mask,
 | 
				
			||||||
		DP_ERR(dev,
 | 
										IB_LINK_LAYER_ETHERNET)) {
 | 
				
			||||||
		       "modify qp: invalid attribute mask=0x%x specified for\n"
 | 
								DP_ERR(dev,
 | 
				
			||||||
		       "qpn=0x%x of type=0x%x old_qp_state=0x%x, new_qp_state=0x%x\n",
 | 
								       "modify qp: invalid attribute mask=0x%x specified for\n"
 | 
				
			||||||
		       attr_mask, qp->qp_id, ibqp->qp_type, old_qp_state,
 | 
								       "qpn=0x%x of type=0x%x old_qp_state=0x%x, new_qp_state=0x%x\n",
 | 
				
			||||||
		       new_qp_state);
 | 
								       attr_mask, qp->qp_id, ibqp->qp_type,
 | 
				
			||||||
		rc = -EINVAL;
 | 
								       old_qp_state, new_qp_state);
 | 
				
			||||||
		goto err;
 | 
								rc = -EINVAL;
 | 
				
			||||||
 | 
								goto err;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Translate the masks... */
 | 
						/* Translate the masks... */
 | 
				
			||||||
| 
						 | 
					@ -2122,15 +2214,17 @@ int qedr_destroy_qp(struct ib_qp *ibqp)
 | 
				
			||||||
	DP_DEBUG(dev, QEDR_MSG_QP, "destroy qp: destroying %p, qp type=%d\n",
 | 
						DP_DEBUG(dev, QEDR_MSG_QP, "destroy qp: destroying %p, qp type=%d\n",
 | 
				
			||||||
		 qp, qp->qp_type);
 | 
							 qp, qp->qp_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((qp->state != QED_ROCE_QP_STATE_RESET) &&
 | 
						if (rdma_protocol_roce(&dev->ibdev, 1)) {
 | 
				
			||||||
	    (qp->state != QED_ROCE_QP_STATE_ERR) &&
 | 
							if ((qp->state != QED_ROCE_QP_STATE_RESET) &&
 | 
				
			||||||
	    (qp->state != QED_ROCE_QP_STATE_INIT)) {
 | 
							    (qp->state != QED_ROCE_QP_STATE_ERR) &&
 | 
				
			||||||
 | 
							    (qp->state != QED_ROCE_QP_STATE_INIT)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		attr.qp_state = IB_QPS_ERR;
 | 
								attr.qp_state = IB_QPS_ERR;
 | 
				
			||||||
		attr_mask |= IB_QP_STATE;
 | 
								attr_mask |= IB_QP_STATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Change the QP state to ERROR */
 | 
								/* Change the QP state to ERROR */
 | 
				
			||||||
		qedr_modify_qp(ibqp, &attr, attr_mask, NULL);
 | 
								qedr_modify_qp(ibqp, &attr, attr_mask, NULL);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (qp->qp_type == IB_QPT_GSI)
 | 
						if (qp->qp_type == IB_QPT_GSI)
 | 
				
			||||||
| 
						 | 
					@ -3025,15 +3119,17 @@ int qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irqsave(&qp->q_lock, flags);
 | 
						spin_lock_irqsave(&qp->q_lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((qp->state != QED_ROCE_QP_STATE_RTS) &&
 | 
						if (rdma_protocol_roce(&dev->ibdev, 1)) {
 | 
				
			||||||
	    (qp->state != QED_ROCE_QP_STATE_ERR) &&
 | 
							if ((qp->state != QED_ROCE_QP_STATE_RTS) &&
 | 
				
			||||||
	    (qp->state != QED_ROCE_QP_STATE_SQD)) {
 | 
							    (qp->state != QED_ROCE_QP_STATE_ERR) &&
 | 
				
			||||||
		spin_unlock_irqrestore(&qp->q_lock, flags);
 | 
							    (qp->state != QED_ROCE_QP_STATE_SQD)) {
 | 
				
			||||||
		*bad_wr = wr;
 | 
								spin_unlock_irqrestore(&qp->q_lock, flags);
 | 
				
			||||||
		DP_DEBUG(dev, QEDR_MSG_CQ,
 | 
								*bad_wr = wr;
 | 
				
			||||||
			 "QP in wrong state! QP icid=0x%x state %d\n",
 | 
								DP_DEBUG(dev, QEDR_MSG_CQ,
 | 
				
			||||||
			 qp->icid, qp->state);
 | 
									 "QP in wrong state! QP icid=0x%x state %d\n",
 | 
				
			||||||
		return -EINVAL;
 | 
									 qp->icid, qp->state);
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (wr) {
 | 
						while (wr) {
 | 
				
			||||||
| 
						 | 
					@ -3153,6 +3249,11 @@ int qedr_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
 | 
				
			||||||
		/* Make sure write sticks */
 | 
							/* Make sure write sticks */
 | 
				
			||||||
		mmiowb();
 | 
							mmiowb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (rdma_protocol_iwarp(&dev->ibdev, 1)) {
 | 
				
			||||||
 | 
								writel(qp->rq.iwarp_db2_data.raw, qp->rq.iwarp_db2);
 | 
				
			||||||
 | 
								mmiowb();	/* for second doorbell */
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wr = wr->next;
 | 
							wr = wr->next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue