Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7cf66041 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'cxgb4-next'



Hariprasad Shenai says:

====================
Misc. fixes for iw_cxgb4

This patch series adds support to determine ingress padding boundary at runtime.
Advertise a larger max read queue depth for qps, and gather the resource limits
from fw and use them to avoid exhausting all the resources and display TPTE on
errors and add support for work request logging feature.

The patches series is created against 'net-next' tree.
And includes patches on cxgb4 and iw_cxgb4 driver.

Since this patch-series contains changes which are dependent on commit id
fc5ab020 ("cxgb4: Replaced the backdoor mechanism to access the HW memory with
PCIe Window method") we would like to request this patch series to get merged
via David Miller's 'net-next' tree.

We have included all the maintainers of respective drivers. Kindly review the
change and let us know in case of any review comments.

V2:
 Optimized alloc_ird function, and several other changes related to debug prints
 based on review comments given by Yann Droneaud.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5ee2c941 7730b4c7
Loading
Loading
Loading
Loading
+57 −23
Original line number Diff line number Diff line
@@ -79,9 +79,10 @@ static int dack_mode = 1;
module_param(dack_mode, int, 0644);
MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=1)");

int c4iw_max_read_depth = 8;
uint c4iw_max_read_depth = 32;
module_param(c4iw_max_read_depth, int, 0644);
MODULE_PARM_DESC(c4iw_max_read_depth, "Per-connection max ORD/IRD (default=8)");
MODULE_PARM_DESC(c4iw_max_read_depth,
		 "Per-connection max ORD/IRD (default=32)");

static int enable_tcp_timestamps;
module_param(enable_tcp_timestamps, int, 0644);
@@ -813,6 +814,8 @@ static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb,
	if (mpa_rev_to_use == 2) {
		mpa->private_data_size = htons(ntohs(mpa->private_data_size) +
					       sizeof (struct mpa_v2_conn_params));
		PDBG("%s initiator ird %u ord %u\n", __func__, ep->ird,
		     ep->ord);
		mpa_v2_params.ird = htons((u16)ep->ird);
		mpa_v2_params.ord = htons((u16)ep->ord);

@@ -1182,8 +1185,8 @@ static int connect_request_upcall(struct c4iw_ep *ep)
			sizeof(struct mpa_v2_conn_params);
	} else {
		/* this means MPA_v1 is used. Send max supported */
		event.ord = c4iw_max_read_depth;
		event.ird = c4iw_max_read_depth;
		event.ord = cur_max_read_depth(ep->com.dev);
		event.ird = cur_max_read_depth(ep->com.dev);
		event.private_data_len = ep->plen;
		event.private_data = ep->mpa_pkt + sizeof(struct mpa_message);
	}
@@ -1247,6 +1250,8 @@ static int update_rx_credits(struct c4iw_ep *ep, u32 credits)
	return credits;
}

#define RELAXED_IRD_NEGOTIATION 1

static int process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
{
	struct mpa_message *mpa;
@@ -1358,18 +1363,34 @@ static int process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
				MPA_V2_IRD_ORD_MASK;
			resp_ord = ntohs(mpa_v2_params->ord) &
				MPA_V2_IRD_ORD_MASK;
			PDBG("%s responder ird %u ord %u ep ird %u ord %u\n",
			     __func__, resp_ird, resp_ord, ep->ird, ep->ord);

			/*
			 * This is a double-check. Ideally, below checks are
			 * not required since ird/ord stuff has been taken
			 * care of in c4iw_accept_cr
			 */
			if ((ep->ird < resp_ord) || (ep->ord > resp_ird)) {
				err = -ENOMEM;
			if (ep->ird < resp_ord) {
				if (RELAXED_IRD_NEGOTIATION && resp_ord <=
				    ep->com.dev->rdev.lldi.max_ordird_qp)
					ep->ird = resp_ord;
				else
					insuff_ird = 1;
			} else if (ep->ird > resp_ord) {
				ep->ird = resp_ord;
			}
			if (ep->ord > resp_ird) {
				if (RELAXED_IRD_NEGOTIATION)
					ep->ord = resp_ird;
				else
					insuff_ird = 1;
			}
			if (insuff_ird) {
				err = -ENOMEM;
				ep->ird = resp_ord;
				ep->ord = resp_ird;
			}

			if (ntohs(mpa_v2_params->ird) &
					MPA_V2_PEER2PEER_MODEL) {
@@ -1571,6 +1592,8 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
				MPA_V2_IRD_ORD_MASK;
			ep->ord = ntohs(mpa_v2_params->ord) &
				MPA_V2_IRD_ORD_MASK;
			PDBG("%s initiator ird %u ord %u\n", __func__, ep->ird,
			     ep->ord);
			if (ntohs(mpa_v2_params->ird) & MPA_V2_PEER2PEER_MODEL)
				if (peer2peer) {
					if (ntohs(mpa_v2_params->ord) &
@@ -2724,8 +2747,8 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
	BUG_ON(!qp);

	set_bit(ULP_ACCEPT, &ep->com.history);
	if ((conn_param->ord > c4iw_max_read_depth) ||
	    (conn_param->ird > c4iw_max_read_depth)) {
	if ((conn_param->ord > cur_max_read_depth(ep->com.dev)) ||
	    (conn_param->ird > cur_max_read_depth(ep->com.dev))) {
		abort_connection(ep, NULL, GFP_KERNEL);
		err = -EINVAL;
		goto err;
@@ -2733,6 +2756,9 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)

	if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) {
		if (conn_param->ord > ep->ird) {
			if (RELAXED_IRD_NEGOTIATION) {
				ep->ord = ep->ird;
			} else {
				ep->ird = conn_param->ird;
				ep->ord = conn_param->ord;
				send_mpa_reject(ep, conn_param->private_data,
@@ -2741,23 +2767,30 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
				err = -ENOMEM;
				goto err;
			}
		if (conn_param->ird > ep->ord) {
			if (!ep->ord)
				conn_param->ird = 1;
			else {
		}
		if (conn_param->ird < ep->ord) {
			if (RELAXED_IRD_NEGOTIATION &&
			    ep->ord <= h->rdev.lldi.max_ordird_qp) {
				conn_param->ird = ep->ord;
			} else {
				abort_connection(ep, NULL, GFP_KERNEL);
				err = -ENOMEM;
				goto err;
			}
		}

	}
	ep->ird = conn_param->ird;
	ep->ord = conn_param->ord;

	if (ep->mpa_attr.version != 2)
	if (ep->mpa_attr.version == 1) {
		if (peer2peer && ep->ird == 0)
			ep->ird = 1;
	} else {
		if (peer2peer &&
		    (ep->mpa_attr.p2p_type != FW_RI_INIT_P2PTYPE_DISABLED) &&
		    (p2p_type == FW_RI_INIT_P2PTYPE_READ_REQ) && ep->ord == 0)
			ep->ird = 1;
	}

	PDBG("%s %d ird %d ord %d\n", __func__, __LINE__, ep->ird, ep->ord);

@@ -2796,6 +2829,7 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
	return 0;
err1:
	ep->com.cm_id = NULL;
	abort_connection(ep, NULL, GFP_KERNEL);
	cm_id->rem_ref(cm_id);
err:
	mutex_unlock(&ep->com.mutex);
@@ -2879,8 +2913,8 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
	int iptype;
	int iwpm_err = 0;

	if ((conn_param->ord > c4iw_max_read_depth) ||
	    (conn_param->ird > c4iw_max_read_depth)) {
	if ((conn_param->ord > cur_max_read_depth(dev)) ||
	    (conn_param->ird > cur_max_read_depth(dev))) {
		err = -EINVAL;
		goto out;
	}
+6 −2
Original line number Diff line number Diff line
@@ -633,11 +633,15 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
		wq->sq.cidx = (uint16_t)idx;
		PDBG("%s completing sq idx %u\n", __func__, wq->sq.cidx);
		*cookie = wq->sq.sw_sq[wq->sq.cidx].wr_id;
		if (c4iw_wr_log)
			c4iw_log_wr_stats(wq, hw_cqe);
		t4_sq_consume(wq);
	} else {
		PDBG("%s completing rq idx %u\n", __func__, wq->rq.cidx);
		*cookie = wq->rq.sw_rq[wq->rq.cidx].wr_id;
		BUG_ON(t4_rq_empty(wq));
		if (c4iw_wr_log)
			c4iw_log_wr_stats(wq, hw_cqe);
		t4_rq_consume(wq);
		goto skip_cqe;
	}
@@ -895,7 +899,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries,
	/*
	 * Make actual HW queue 2x to avoid cdix_inc overflows.
	 */
	hwentries = min(entries * 2, T4_MAX_IQ_SIZE);
	hwentries = min(entries * 2, rhp->rdev.hw_queue.t4_max_iq_size);

	/*
	 * Make HW queue at least 64 entries so GTS updates aren't too
@@ -912,7 +916,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries,
	if (ucontext) {
		memsize = roundup(memsize, PAGE_SIZE);
		hwentries = memsize / sizeof *chp->cq.queue;
		while (hwentries > T4_MAX_IQ_SIZE) {
		while (hwentries > rhp->rdev.hw_queue.t4_max_iq_size) {
			memsize -= PAGE_SIZE;
			hwentries = memsize / sizeof *chp->cq.queue;
		}
+184 −4
Original line number Diff line number Diff line
@@ -55,6 +55,15 @@ module_param(allow_db_coalescing_on_t5, int, 0644);
MODULE_PARM_DESC(allow_db_coalescing_on_t5,
		 "Allow DB Coalescing on T5 (default = 0)");

int c4iw_wr_log = 0;
module_param(c4iw_wr_log, int, 0444);
MODULE_PARM_DESC(c4iw_wr_log, "Enables logging of work request timing data.");

int c4iw_wr_log_size_order = 12;
module_param(c4iw_wr_log_size_order, int, 0444);
MODULE_PARM_DESC(c4iw_wr_log_size_order,
		 "Number of entries (log2) in the work request timing log.");

struct uld_ctx {
	struct list_head entry;
	struct cxgb4_lld_info lldi;
@@ -103,6 +112,117 @@ static ssize_t debugfs_read(struct file *file, char __user *buf, size_t count,
	return simple_read_from_buffer(buf, count, ppos, d->buf, d->pos);
}

void c4iw_log_wr_stats(struct t4_wq *wq, struct t4_cqe *cqe)
{
	struct wr_log_entry le;
	int idx;

	if (!wq->rdev->wr_log)
		return;

	idx = (atomic_inc_return(&wq->rdev->wr_log_idx) - 1) &
		(wq->rdev->wr_log_size - 1);
	le.poll_sge_ts = cxgb4_read_sge_timestamp(wq->rdev->lldi.ports[0]);
	getnstimeofday(&le.poll_host_ts);
	le.valid = 1;
	le.cqe_sge_ts = CQE_TS(cqe);
	if (SQ_TYPE(cqe)) {
		le.qid = wq->sq.qid;
		le.opcode = CQE_OPCODE(cqe);
		le.post_host_ts = wq->sq.sw_sq[wq->sq.cidx].host_ts;
		le.post_sge_ts = wq->sq.sw_sq[wq->sq.cidx].sge_ts;
		le.wr_id = CQE_WRID_SQ_IDX(cqe);
	} else {
		le.qid = wq->rq.qid;
		le.opcode = FW_RI_RECEIVE;
		le.post_host_ts = wq->rq.sw_rq[wq->rq.cidx].host_ts;
		le.post_sge_ts = wq->rq.sw_rq[wq->rq.cidx].sge_ts;
		le.wr_id = CQE_WRID_MSN(cqe);
	}
	wq->rdev->wr_log[idx] = le;
}

static int wr_log_show(struct seq_file *seq, void *v)
{
	struct c4iw_dev *dev = seq->private;
	struct timespec prev_ts = {0, 0};
	struct wr_log_entry *lep;
	int prev_ts_set = 0;
	int idx, end;

#define ts2ns(ts) ((ts) * dev->rdev.lldi.cclk_ps / 1000)

	idx = atomic_read(&dev->rdev.wr_log_idx) &
		(dev->rdev.wr_log_size - 1);
	end = idx - 1;
	if (end < 0)
		end = dev->rdev.wr_log_size - 1;
	lep = &dev->rdev.wr_log[idx];
	while (idx != end) {
		if (lep->valid) {
			if (!prev_ts_set) {
				prev_ts_set = 1;
				prev_ts = lep->poll_host_ts;
			}
			seq_printf(seq, "%04u: sec %lu nsec %lu qid %u opcode "
				   "%u %s 0x%x host_wr_delta sec %lu nsec %lu "
				   "post_sge_ts 0x%llx cqe_sge_ts 0x%llx "
				   "poll_sge_ts 0x%llx post_poll_delta_ns %llu "
				   "cqe_poll_delta_ns %llu\n",
				   idx,
				   timespec_sub(lep->poll_host_ts,
						prev_ts).tv_sec,
				   timespec_sub(lep->poll_host_ts,
						prev_ts).tv_nsec,
				   lep->qid, lep->opcode,
				   lep->opcode == FW_RI_RECEIVE ?
							"msn" : "wrid",
				   lep->wr_id,
				   timespec_sub(lep->poll_host_ts,
						lep->post_host_ts).tv_sec,
				   timespec_sub(lep->poll_host_ts,
						lep->post_host_ts).tv_nsec,
				   lep->post_sge_ts, lep->cqe_sge_ts,
				   lep->poll_sge_ts,
				   ts2ns(lep->poll_sge_ts - lep->post_sge_ts),
				   ts2ns(lep->poll_sge_ts - lep->cqe_sge_ts));
			prev_ts = lep->poll_host_ts;
		}
		idx++;
		if (idx > (dev->rdev.wr_log_size - 1))
			idx = 0;
		lep = &dev->rdev.wr_log[idx];
	}
#undef ts2ns
	return 0;
}

static int wr_log_open(struct inode *inode, struct file *file)
{
	return single_open(file, wr_log_show, inode->i_private);
}

static ssize_t wr_log_clear(struct file *file, const char __user *buf,
			    size_t count, loff_t *pos)
{
	struct c4iw_dev *dev = ((struct seq_file *)file->private_data)->private;
	int i;

	if (dev->rdev.wr_log)
		for (i = 0; i < dev->rdev.wr_log_size; i++)
			dev->rdev.wr_log[i].valid = 0;
	return count;
}

static const struct file_operations wr_log_debugfs_fops = {
	.owner   = THIS_MODULE,
	.open    = wr_log_open,
	.release = single_release,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.write   = wr_log_clear,
};

static int dump_qp(int id, void *p, void *data)
{
	struct c4iw_qp *qp = p;
@@ -241,12 +361,32 @@ static int dump_stag(int id, void *p, void *data)
	struct c4iw_debugfs_data *stagd = data;
	int space;
	int cc;
	struct fw_ri_tpte tpte;
	int ret;

	space = stagd->bufsize - stagd->pos - 1;
	if (space == 0)
		return 1;

	cc = snprintf(stagd->buf + stagd->pos, space, "0x%x\n", id<<8);
	ret = cxgb4_read_tpte(stagd->devp->rdev.lldi.ports[0], (u32)id<<8,
			      (__be32 *)&tpte);
	if (ret) {
		dev_err(&stagd->devp->rdev.lldi.pdev->dev,
			"%s cxgb4_read_tpte err %d\n", __func__, ret);
		return ret;
	}
	cc = snprintf(stagd->buf + stagd->pos, space,
		      "stag: idx 0x%x valid %d key 0x%x state %d pdid %d "
		      "perm 0x%x ps %d len 0x%llx va 0x%llx\n",
		      (u32)id<<8,
		      G_FW_RI_TPTE_VALID(ntohl(tpte.valid_to_pdid)),
		      G_FW_RI_TPTE_STAGKEY(ntohl(tpte.valid_to_pdid)),
		      G_FW_RI_TPTE_STAGSTATE(ntohl(tpte.valid_to_pdid)),
		      G_FW_RI_TPTE_PDID(ntohl(tpte.valid_to_pdid)),
		      G_FW_RI_TPTE_PERM(ntohl(tpte.locread_to_qpid)),
		      G_FW_RI_TPTE_PS(ntohl(tpte.locread_to_qpid)),
		      ((u64)ntohl(tpte.len_hi) << 32) | ntohl(tpte.len_lo),
		      ((u64)ntohl(tpte.va_hi) << 32) | ntohl(tpte.va_lo_fbo));
	if (cc < space)
		stagd->pos += cc;
	return 0;
@@ -259,7 +399,7 @@ static int stag_release(struct inode *inode, struct file *file)
		printk(KERN_INFO "%s null stagd?\n", __func__);
		return 0;
	}
	kfree(stagd->buf);
	vfree(stagd->buf);
	kfree(stagd);
	return 0;
}
@@ -282,8 +422,8 @@ static int stag_open(struct inode *inode, struct file *file)
	idr_for_each(&stagd->devp->mmidr, count_idrs, &count);
	spin_unlock_irq(&stagd->devp->lock);

	stagd->bufsize = count * sizeof("0x12345678\n");
	stagd->buf = kmalloc(stagd->bufsize, GFP_KERNEL);
	stagd->bufsize = count * 256;
	stagd->buf = vmalloc(stagd->bufsize);
	if (!stagd->buf) {
		ret = -ENOMEM;
		goto err1;
@@ -348,6 +488,7 @@ static int stats_show(struct seq_file *seq, void *v)
		   dev->rdev.stats.act_ofld_conn_fails);
	seq_printf(seq, "PAS_OFLD_CONN_FAILS: %10llu\n",
		   dev->rdev.stats.pas_ofld_conn_fails);
	seq_printf(seq, "AVAILABLE IRD: %10u\n", dev->avail_ird);
	return 0;
}

@@ -583,6 +724,12 @@ static int setup_debugfs(struct c4iw_dev *devp)
	if (de && de->d_inode)
		de->d_inode->i_size = 4096;

	if (c4iw_wr_log) {
		de = debugfs_create_file("wr_log", S_IWUSR, devp->debugfs_root,
					 (void *)devp, &wr_log_debugfs_fops);
		if (de && de->d_inode)
			de->d_inode->i_size = 4096;
	}
	return 0;
}

@@ -696,6 +843,16 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
		pr_err(MOD "error allocating status page\n");
		goto err4;
	}
	if (c4iw_wr_log) {
		rdev->wr_log = kzalloc((1 << c4iw_wr_log_size_order) *
				       sizeof(*rdev->wr_log), GFP_KERNEL);
		if (rdev->wr_log) {
			rdev->wr_log_size = 1 << c4iw_wr_log_size_order;
			atomic_set(&rdev->wr_log_idx, 0);
		} else {
			pr_err(MOD "error allocating wr_log. Logging disabled\n");
		}
	}
	return 0;
err4:
	c4iw_rqtpool_destroy(rdev);
@@ -709,6 +866,7 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)

static void c4iw_rdev_close(struct c4iw_rdev *rdev)
{
	kfree(rdev->wr_log);
	free_page((unsigned long)rdev->status_page);
	c4iw_pblpool_destroy(rdev);
	c4iw_rqtpool_destroy(rdev);
@@ -768,6 +926,27 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
	}
	devp->rdev.lldi = *infop;

	/* init various hw-queue params based on lld info */
	PDBG("%s: Ing. padding boundary is %d, egrsstatuspagesize = %d\n",
	     __func__, devp->rdev.lldi.sge_ingpadboundary,
	     devp->rdev.lldi.sge_egrstatuspagesize);

	devp->rdev.hw_queue.t4_eq_status_entries =
		devp->rdev.lldi.sge_ingpadboundary > 64 ? 2 : 1;
	devp->rdev.hw_queue.t4_max_eq_size =
		65520 - devp->rdev.hw_queue.t4_eq_status_entries;
	devp->rdev.hw_queue.t4_max_iq_size = 65520 - 1;
	devp->rdev.hw_queue.t4_max_rq_size =
		8192 - devp->rdev.hw_queue.t4_eq_status_entries;
	devp->rdev.hw_queue.t4_max_sq_size =
		devp->rdev.hw_queue.t4_max_eq_size - 1;
	devp->rdev.hw_queue.t4_max_qp_depth =
		devp->rdev.hw_queue.t4_max_rq_size - 1;
	devp->rdev.hw_queue.t4_max_cq_depth =
		devp->rdev.hw_queue.t4_max_iq_size - 1;
	devp->rdev.hw_queue.t4_stat_len =
		devp->rdev.lldi.sge_egrstatuspagesize;

	/*
	 * For T5 devices, we map all of BAR2 with WC.
	 * For T4 devices with onchip qp mem, we map only that part
@@ -818,6 +997,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
	mutex_init(&devp->rdev.stats.lock);
	mutex_init(&devp->db_mutex);
	INIT_LIST_HEAD(&devp->db_fc_list);
	devp->avail_ird = devp->rdev.lldi.max_ird_adapter;

	if (c4iw_debugfs_root) {
		devp->debugfs_root = debugfs_create_dir(
+50 −5
Original line number Diff line number Diff line
@@ -35,6 +35,55 @@

#include "iw_cxgb4.h"

static void print_tpte(struct c4iw_dev *dev, u32 stag)
{
	int ret;
	struct fw_ri_tpte tpte;

	ret = cxgb4_read_tpte(dev->rdev.lldi.ports[0], stag,
			      (__be32 *)&tpte);
	if (ret) {
		dev_err(&dev->rdev.lldi.pdev->dev,
			"%s cxgb4_read_tpte err %d\n", __func__, ret);
		return;
	}
	PDBG("stag idx 0x%x valid %d key 0x%x state %d pdid %d "
	       "perm 0x%x ps %d len 0x%llx va 0x%llx\n",
	       stag & 0xffffff00,
	       G_FW_RI_TPTE_VALID(ntohl(tpte.valid_to_pdid)),
	       G_FW_RI_TPTE_STAGKEY(ntohl(tpte.valid_to_pdid)),
	       G_FW_RI_TPTE_STAGSTATE(ntohl(tpte.valid_to_pdid)),
	       G_FW_RI_TPTE_PDID(ntohl(tpte.valid_to_pdid)),
	       G_FW_RI_TPTE_PERM(ntohl(tpte.locread_to_qpid)),
	       G_FW_RI_TPTE_PS(ntohl(tpte.locread_to_qpid)),
	       ((u64)ntohl(tpte.len_hi) << 32) | ntohl(tpte.len_lo),
	       ((u64)ntohl(tpte.va_hi) << 32) | ntohl(tpte.va_lo_fbo));
}

static void dump_err_cqe(struct c4iw_dev *dev, struct t4_cqe *err_cqe)
{
	__be64 *p = (void *)err_cqe;

	dev_err(&dev->rdev.lldi.pdev->dev,
		"AE qpid %d opcode %d status 0x%x "
		"type %d len 0x%x wrid.hi 0x%x wrid.lo 0x%x\n",
		CQE_QPID(err_cqe), CQE_OPCODE(err_cqe),
		CQE_STATUS(err_cqe), CQE_TYPE(err_cqe), ntohl(err_cqe->len),
		CQE_WRID_HI(err_cqe), CQE_WRID_LOW(err_cqe));

	PDBG("%016llx %016llx %016llx %016llx\n",
	     be64_to_cpu(p[0]), be64_to_cpu(p[1]), be64_to_cpu(p[2]),
	     be64_to_cpu(p[3]));

	/*
	 * Ingress WRITE and READ_RESP errors provide
	 * the offending stag, so parse and log it.
	 */
	if (RQ_TYPE(err_cqe) && (CQE_OPCODE(err_cqe) == FW_RI_RDMA_WRITE ||
				 CQE_OPCODE(err_cqe) == FW_RI_READ_RESP))
		print_tpte(dev, CQE_WRID_STAG(err_cqe));
}

static void post_qp_event(struct c4iw_dev *dev, struct c4iw_cq *chp,
			  struct c4iw_qp *qhp,
			  struct t4_cqe *err_cqe,
@@ -44,11 +93,7 @@ static void post_qp_event(struct c4iw_dev *dev, struct c4iw_cq *chp,
	struct c4iw_qp_attributes attrs;
	unsigned long flag;

	printk(KERN_ERR MOD "AE qpid 0x%x opcode %d status 0x%x "
	       "type %d wrid.hi 0x%x wrid.lo 0x%x\n",
	       CQE_QPID(err_cqe), CQE_OPCODE(err_cqe),
	       CQE_STATUS(err_cqe), CQE_TYPE(err_cqe),
	       CQE_WRID_HI(err_cqe), CQE_WRID_LOW(err_cqe));
	dump_err_cqe(dev, err_cqe);

	if (qhp->attr.state == C4IW_QP_STATE_RTS) {
		attrs.next_state = C4IW_QP_STATE_TERMINATE;
+37 −1
Original line number Diff line number Diff line
@@ -139,6 +139,29 @@ struct c4iw_stats {
	u64  pas_ofld_conn_fails;
};

struct c4iw_hw_queue {
	int t4_eq_status_entries;
	int t4_max_eq_size;
	int t4_max_iq_size;
	int t4_max_rq_size;
	int t4_max_sq_size;
	int t4_max_qp_depth;
	int t4_max_cq_depth;
	int t4_stat_len;
};

struct wr_log_entry {
	struct timespec post_host_ts;
	struct timespec poll_host_ts;
	u64 post_sge_ts;
	u64 cqe_sge_ts;
	u64 poll_sge_ts;
	u16 qid;
	u16 wr_id;
	u8 opcode;
	u8 valid;
};

struct c4iw_rdev {
	struct c4iw_resource resource;
	unsigned long qpshift;
@@ -156,7 +179,11 @@ struct c4iw_rdev {
	unsigned long oc_mw_pa;
	void __iomem *oc_mw_kva;
	struct c4iw_stats stats;
	struct c4iw_hw_queue hw_queue;
	struct t4_dev_status_page *status_page;
	atomic_t wr_log_idx;
	struct wr_log_entry *wr_log;
	int wr_log_size;
};

static inline int c4iw_fatal_error(struct c4iw_rdev *rdev)
@@ -237,6 +264,7 @@ struct c4iw_dev {
	struct idr atid_idr;
	struct idr stid_idr;
	struct list_head db_fc_list;
	u32 avail_ird;
};

static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
@@ -318,6 +346,13 @@ static inline void remove_handle_nolock(struct c4iw_dev *rhp,
	_remove_handle(rhp, idr, id, 0);
}

extern uint c4iw_max_read_depth;

static inline int cur_max_read_depth(struct c4iw_dev *dev)
{
	return min(dev->rdev.lldi.max_ordird_qp, c4iw_max_read_depth);
}

struct c4iw_pd {
	struct ib_pd ibpd;
	u32 pdid;
@@ -991,7 +1026,8 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe);

extern struct cxgb4_client t4c_client;
extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS];
extern int c4iw_max_read_depth;
extern void c4iw_log_wr_stats(struct t4_wq *wq, struct t4_cqe *cqe);
extern int c4iw_wr_log;
extern int db_fc_threshold;
extern int db_coalescing_threshold;
extern int use_dsgl;
Loading