@@ -936,17 +936,11 @@ void qedi_fp_process_cqes(struct qedi_work *work)
static void qedi_ring_doorbell(struct qedi_conn *qedi_conn)
{
- struct iscsi_db_data dbell = { 0 };
+ qedi_conn->ep->db_data.sq_prod = qedi_conn->ep->fw_sq_prod_idx
- dbell.agg_flags = 0;
-
- dbell.params |= DB_DEST_XCM << ISCSI_DB_DATA_DEST_SHIFT;
- dbell.params |= DB_AGG_CMD_SET << ISCSI_DB_DATA_AGG_CMD_SHIFT;
- dbell.params |=
- DQ_XCM_ISCSI_SQ_PROD_CMD << ISCSI_DB_DATA_AGG_VAL_SEL_SHIFT;
-
- dbell.sq_prod = qedi_conn->ep->fw_sq_prod_idx;
- writel(*(u32 *)&dbell, qedi_conn->ep->p_doorbell);
+ /* wmb - Make sure fw idx is coherent */
+ wmb();
+ writel(*(u32 *)&qedi_conn->ep->db_data, qedi_conn->ep->p_doorbell);
/* Make sure fw write idx is coherent, and include both memory barriers
* as a failsafe as for some architectures the call is the same but on
@@ -499,8 +499,9 @@ static u16 qedi_calc_mss(u16 pmtu, u8 is_ipv6, u8 tcp_ts_en, u8 vlan_en)
static int qedi_iscsi_offload_conn(struct qedi_endpoint *qedi_ep)
{
- struct qedi_ctx *qedi = qedi_ep->qedi;
struct qed_iscsi_params_offload *conn_info;
+ struct qedi_ctx *qedi = qedi_ep->qedi;
+ struct qedi_ep->db_data.params
int rval;
int i;
@@ -577,8 +578,33 @@ static int qedi_iscsi_offload_conn(struct qedi_endpoint *qedi_ep)
"Default cq index [%d], mss [%d]\n",
conn_info->default_cq, conn_info->mss);
+ /* Prepare the doorbell parameters */
+ qedi_ep->db_data.agg_flags = 0;
+ qedi_ep->db_data.params = 0;
+ SET_FIELD(qedi_ep->db_data.params, ISCSI_DB_DATA_DEST, DB_DEST_XCM);
+ SET_FIELD(qedi_ep->db_data.params, ISCSI_DB_DATA_AGG_CMD,
+ DB_AGG_CMD_MAX);
+ SET_FIELD(qedi_ep->db_data.params, ISCSI_DB_DATA_AGG_VAL_SEL,
+ DQ_XCM_ISCSI_SQ_PROD_CMD);
+ SET_FIELD(qedi_ep->db_data.params, ISCSI_DB_DATA_BYPASS_EN, 1);
+
+ /* register doorbell with doorbell recovery mechanism */
+ rc = qedi_ops->common->db_recovery_add(qedi->cdev,
+ qedi_ep.p_doorbell,
+ &qedi_ep.db_data,
+ DB_REC_WIDTH_32B, DB_REC_KERNEL);
+ if (rc) {
+ kfree(conn_info);
+ return rval;
+ }
+
rval = qedi_ops->offload_conn(qedi->cdev, qedi_ep->handle, conn_info);
if (rval)
+ /* delete doorbell from doorbell recovery mechanism */
+ rc = qedi_ops->common->db_recovery_del(qedi->cdev,
+ qedi_ep.p_doorbell,
+ &qedi_ep.db_data);
+
QEDI_ERR(&qedi->dbg_ctx, "offload_conn returned %d, ep=%p\n",
rval, qedi_ep);
@@ -1100,6 +1126,11 @@ static void qedi_ep_disconnect(struct iscsi_endpoint *ep)
break;
}
+ /* delete doorbell from doorbell recovery mechanism */
+ rc = qedi_ops->common->db_recovery_del(qedi->cdev,
+ qedi_ep.p_doorbell,
+ &qedi_ep.db_data);
+
if (!abrt_conn)
wait_delay += qedi->pf_params.iscsi_pf_params.two_msl_timer;
@@ -80,6 +80,7 @@ struct qedi_endpoint {
u32 handle;
u32 fw_cid;
void __iomem *p_doorbell;
+ struct iscsi_db_data db_data;
/* Send queue management */
struct iscsi_wqe *sq;