/*
 * cxgb3i_ddp.c: Chelsio S3xx iSCSI DDP Manager.
 *
 * Copyright (c) 2008 Chelsio Communications, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Written by: Karen Xie (kxie@chelsio.com)
 */

#include <linux/skbuff.h>
#include <linux/scatterlist.h>

/* from cxgb3 LLD */
#include "common.h"
#include "t3_cpl.h"
#include "t3cdev.h"
#include "cxgb3_ctl_defs.h"
#include "cxgb3_offload.h"
#include "firmware_exports.h"

#include "cxgb3i_ddp.h"

#define ddp_log_error(fmt...) printk(KERN_ERR "cxgb3i_ddp: ERR! " fmt)
#define ddp_log_warn(fmt...)  printk(KERN_WARNING "cxgb3i_ddp: WARN! " fmt)
#define ddp_log_info(fmt...)  printk(KERN_INFO "cxgb3i_ddp: " fmt)

#ifdef __DEBUG_CXGB3I_DDP__
#define ddp_log_debug(fmt, args...) \
	printk(KERN_INFO "cxgb3i_ddp: %s - " fmt, __func__ , ## args)
#else
#define ddp_log_debug(fmt...)
#endif

/*
 * iSCSI Direct Data Placement
 *
 * T3 h/w can directly place the iSCSI Data-In or Data-Out PDU's payload into
 * pre-posted final destination host-memory buffers based on the Initiator
 * Task Tag (ITT) in Data-In or Target Task Tag (TTT) in Data-Out PDUs.
 *
 * The host memory address is programmed into h/w in the format of pagepod
 * entries.
 * The location of the pagepod entry is encoded into ddp tag which is used or
 * is the base for ITT/TTT.
 */

#define DDP_PGIDX_MAX		4
#define DDP_THRESHOLD	2048
static unsigned char ddp_page_order[DDP_PGIDX_MAX] = {0, 1, 2, 4};
static unsigned char ddp_page_shift[DDP_PGIDX_MAX] = {12, 13, 14, 16};
static unsigned char page_idx = DDP_PGIDX_MAX;

/*
 * functions to program the pagepod in h/w
 */
static inline void ulp_mem_io_set_hdr(struct sk_buff *skb, unsigned int addr)
{
	struct ulp_mem_io *req = (struct ulp_mem_io *)skb->head;

	req->wr.wr_lo = 0;
	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_BYPASS));
	req->cmd_lock_addr = htonl(V_ULP_MEMIO_ADDR(addr >> 5) |
				   V_ULPTX_CMD(ULP_MEM_WRITE));
	req->len = htonl(V_ULP_MEMIO_DATA_LEN(PPOD_SIZE >> 5) |
			 V_ULPTX_NFLITS((PPOD_SIZE >> 3) + 1));
}

static int set_ddp_map(struct cxgb3i_ddp_info *ddp, struct pagepod_hdr *hdr,
		       unsigned int idx, unsigned int npods,
		       struct cxgb3i_gather_list *gl)
{
	unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
	int i;

	for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
		struct sk_buff *skb = ddp->gl_skb[idx];
		struct pagepod *ppod;
		int j, pidx;

		/* hold on to the skb until we clear the ddp mapping */
		skb_get(skb);

		ulp_mem_io_set_hdr(skb, pm_addr);
		ppod = (struct pagepod *)
		       (skb->head + sizeof(struct ulp_mem_io));
		memcpy(&(ppod->hdr), hdr, sizeof(struct pagepod));
		for (pidx = 4 * i, j = 0; j < 5; ++j, ++pidx)
			ppod->addr[j] = pidx < gl->nelem ?
				     cpu_to_be64(gl->phys_addr[pidx]) : 0UL;

		skb->priority = CPL_PRIORITY_CONTROL;
		cxgb3_ofld_send(ddp->tdev, skb);
	}
	return 0;
}

static void clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int tag,
			 unsigned int idx, unsigned int npods)
{
	unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
	int i;

	for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
		struct sk_buff *skb = ddp->gl_skb[idx];

		if (!skb) {
			ddp_log_error("ddp tag 0x%x, 0x%x, %d/%u, skb NULL.\n",
					tag, idx, i, npods);
			continue;
		}
		ddp->gl_skb[idx] = NULL;
		memset((skb->head + sizeof(struct ulp_mem_io)), 0, PPOD_SIZE);
		ulp_mem_io_set_hdr(skb, pm_addr);
		skb->priority = CPL_PRIORITY_CONTROL;
		cxgb3_ofld_send(ddp->tdev, skb);
	}
}

static inline int ddp_find_unused_entries(struct cxgb3i_ddp_info *ddp,
					  int start, int max, int count,
					  struct cxgb3i_gather_list *gl)
{
	unsigned int i, j;

	spin_lock(&ddp->map_lock);
	for (i = start; i <= max;) {
		for (j = 0; j < count; j++) {
			if (ddp->gl_map[i + j])
				break;
		}
		if (j == count) {
			for (j = 0; j < count; j++)
				ddp->gl_map[i + j] = gl;
			spin_unlock(&ddp->map_lock);
			return i;
		}
		i += j + 1;
	}
	spin_unlock(&ddp->map_lock);
	return -EBUSY;
}

static inline void ddp_unmark_entries(struct cxgb3i_ddp_info *ddp,
				      int start, int count)
{
	spin_lock(&ddp->map_lock);
	memset(&ddp->gl_map[start], 0,
	       count * sizeof(struct cxgb3i_gather_list *));
	spin_unlock(&ddp->map_lock);
}

static inline void ddp_free_gl_skb(struct cxgb3i_ddp_info *ddp,
				   int idx, int count)
{
	int i;

	for (i = 0; i < count; i++, idx++)
		if (ddp->gl_skb[idx]) {
			kfree_skb(ddp->gl_skb[idx]);
			ddp->gl_skb[idx] = NULL;
		}
}

static inline int ddp_alloc_gl_skb(struct cxgb3i_ddp_info *ddp, int idx,
				   int count, gfp_t gfp)
{
	int i;

	for (i = 0; i < count; i++) {
		struct sk_buff *skb = alloc_skb(sizeof(struct ulp_mem_io) +
						PPOD_SIZE, gfp);
		if (skb) {
			ddp->gl_skb[idx + i] = skb;
			skb_put(skb, sizeof(struct ulp_mem_io) + PPOD_SIZE);
		} else {
			ddp_free_gl_skb(ddp, idx, i);
			return -ENOMEM;
		}
	}
	return 0;
}

/**
 * cxgb3i_ddp_find_page_index - return ddp page index for a given page size
 * @pgsz: page size
 * return the ddp page index, if no match is found return DDP_PGIDX_MAX.
 */
int cxgb3i_ddp_find_page_index(unsigned long pgsz)
{
	int i;

	for (i = 0; i < DDP_PGIDX_MAX; i++) {
		if (pgsz == (1UL << ddp_page_shift[i]))
			return i;
	}
	ddp_log_debug("ddp page size 0x%lx not supported.\n", pgsz);
	return DDP_PGIDX_MAX;
}

static inline void ddp_gl_unmap(struct pci_dev *pdev,
				struct cxgb3i_gather_list *gl)
{
	int i;

	for (i = 0; i < gl->nelem; i++)
		pci_unmap_page(pdev, gl->phys_addr[i], PAGE_SIZE,
			       PCI_DMA_FROMDEVICE);
}

static inline int ddp_gl_map(struct pci_dev *pdev,
			     struct cxgb3i_gather_list *gl)
{
	int i;

	for (i = 0; i < gl->nelem; i++) {
		gl->phys_addr[i] = pci_map_page(pdev, gl->pages[i], 0,
						PAGE_SIZE,
						PCI_DMA_FROMDEVICE);
		if (unlikely(pci_dma_mapping_error(pdev, gl->phys_addr[i])))
			goto unmap;
	}

	return i;

unmap:
	if (i) {
		unsigned int nelem = gl->nelem;

		gl->nelem = i;
		ddp_gl_unmap(pdev, gl);
		gl->nelem = nelem;
	}
	return -ENOMEM;
}

/**
 * cxgb3i_ddp_make_gl - build ddp page buffer list
 * @xferlen: total buffer length
 * @sgl: page buffer scatter-gather list
 * @sgcnt: # of page buffers
 * @pdev: pci_dev, used for pci map
 * @gfp: allocation mode
 *
 * construct a ddp page buffer list from the scsi scattergather list.
 * coalesce buffers as much as possible, and obtain dma addresses for
 * each page.
 *
 * Return the cxgb3i_gather_list constructed from the page buffers if the
 * memory can be used for ddp. Return NULL otherwise.
 */
struct cxgb3i_gather_list *cxgb3i_ddp_make_gl(unsigned int xferlen,
					      struct scatterlist *sgl,
					      unsigned int sgcnt,
					      struct pci_dev *pdev,
					      gfp_t gfp)
{
	struct cxgb3i_gather_list *gl;
	struct scatterlist *sg = sgl;
	struct page *sgpage = sg_page(sg);
	unsigned int sglen = sg->length;
	unsigned int sgoffset = sg->offset;
	unsigned int npages = (xferlen + sgoffset + PAGE_SIZE - 1) >>
			      PAGE_SHIFT;
	int i = 1, j = 0;

	if (xferlen < DDP_THRESHOLD) {
		ddp_log_debug("xfer %u < threshold %u, no ddp.\n",
			      xferlen, DDP_THRESHOLD);
		return NULL;
	}

	gl = kzalloc(sizeof(struct cxgb3i_gather_list) +
		     npages * (sizeof(dma_addr_t) + sizeof(struct page *)),
		     gfp);
	if (!gl)
		return NULL;

	gl->pages = (struct page **)&gl->phys_addr[npages];
	gl->length = xferlen;
	gl->offset = sgoffset;
	gl->pages[0] = sgpage;

	sg = sg_next(sg);
	while (sg) {
		struct page *page = sg_page(sg);

		if (sgpage == page && sg->offset == sgoffset + sglen)
			sglen += sg->length;
		else {
			/* make sure the sgl is fit for ddp:
			 * each has the same page size, and
			 * all of the middle pages are used completely
			 */
			if ((j && sgoffset) ||
			    ((i != sgcnt - 1) &&
			     ((sglen + sgoffset) & ~PAGE_MASK)))
				goto error_out;

			j++;
			if (j == gl->nelem || sg->offset)
				goto error_out;
			gl->pages[j] = page;
			sglen = sg->length;
			sgoffset = sg->offset;
			sgpage = page;
		}
		i++;
		sg = sg_next(sg);
	}
	gl->nelem = ++j;

	if (ddp_gl_map(pdev, gl) < 0)
		goto error_out;

	return gl;

error_out:
	kfree(gl);
	return NULL;
}

/**
 * cxgb3i_ddp_release_gl - release a page buffer list
 * @gl: a ddp page buffer list
 * @pdev: pci_dev used for pci_unmap
 * free a ddp page buffer list resulted from cxgb3i_ddp_make_gl().
 */
void cxgb3i_ddp_release_gl(struct cxgb3i_gather_list *gl,
			   struct pci_dev *pdev)
{
	ddp_gl_unmap(pdev, gl);
	kfree(gl);
}

/**
 * cxgb3i_ddp_tag_reserve - set up ddp for a data transfer
 * @tdev: t3cdev adapter
 * @tid: connection id
 * @tformat: tag format
 * @tagp: contains s/w tag initially, will be updated with ddp/hw tag
 * @gl: the page momory list
 * @gfp: allocation mode
 *
 * ddp setup for a given page buffer list and construct the ddp tag.
 * return 0 if success, < 0 otherwise.
 */
int cxgb3i_ddp_tag_reserve(struct t3cdev *tdev, unsigned int tid,
			   struct cxgb3i_tag_format *tformat, u32 *tagp,
			   struct cxgb3i_gather_list *gl, gfp_t gfp)
{
	struct cxgb3i_ddp_info *ddp = tdev->ulp_iscsi;
	struct pagepod_hdr hdr;
	unsigned int npods;
	int idx = -1, idx_max;
	int err = -ENOMEM;
	u32 sw_tag = *tagp;
	u32 tag;

	if (page_idx >= DDP_PGIDX_MAX || !ddp || !gl || !gl->nelem ||
		gl->length < DDP_THRESHOLD) {
		ddp_log_debug("pgidx %u, xfer %u/%u, NO ddp.\n",
			      page_idx, gl->length, DDP_THRESHOLD);
		return -EINVAL;
	}

	npods = (gl->nelem + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
	idx_max = ddp->nppods - npods + 1;

	if (ddp->idx_last == ddp->nppods)
		idx = ddp_find_unused_entries(ddp, 0, idx_max, npods, gl);
	else {
		idx = ddp_find_unused_entries(ddp, ddp->idx_last + 1,
					      idx_max, npods, gl);
		if (idx < 0 && ddp->idx_last >= npods)
			idx = ddp_find_unused_entries(ddp, 0,
						      ddp->idx_last - npods + 1,
						      npods, gl);
	}
	if (idx < 0) {
		ddp_log_debug("xferlen %u, gl %u, npods %u NO DDP.\n",
			      gl->length, gl->nelem, npods);
		return idx;
	}

	err = ddp_alloc_gl_skb(ddp, idx, npods, gfp);
	if (err < 0)
		goto unmark_entries;

	tag = cxgb3i_ddp_tag_base(tformat, sw_tag);
	tag |= idx << PPOD_IDX_SHIFT;

	hdr.rsvd = 0;
	hdr.vld_tid = htonl(F_PPOD_VALID | V_PPOD_TID(tid));
	hdr.pgsz_tag_clr = htonl(tag & ddp->rsvd_tag_mask);
	hdr.maxoffset = htonl(gl->length);
	hdr.pgoffset = htonl(gl->offset);

	err = set_ddp_map(ddp, &hdr, idx, npods, gl);
	if (err < 0)
		goto free_gl_skb;

	ddp->idx_last = idx;
	ddp_log_debug("xfer %u, gl %u,%u, tid 0x%x, 0x%x -> 0x%x(%u,%u).\n",
		      gl->length, gl->nelem, gl->offset, tid, sw_tag, tag,
		      idx, npods);
	*tagp = tag;
	return 0;

free_gl_skb:
	ddp_free_gl_skb(ddp, idx, npods);
unmark_entries:
	ddp_unmark_entries(ddp, idx, npods);
	return err;
}

/**
 * cxgb3i_ddp_tag_release - release a ddp tag
 * @tdev: t3cdev adapter
 * @tag: ddp tag
 * ddp cleanup for a given ddp tag and release all the resources held
 */
void cxgb3i_ddp_tag_release(struct t3cdev *tdev, u32 tag)
{
	struct cxgb3i_ddp_info *ddp = tdev->ulp_iscsi;
	u32 idx;

	if (!ddp) {
		ddp_log_error("release ddp tag 0x%x, ddp NULL.\n", tag);
		return;
	}

	idx = (tag >> PPOD_IDX_SHIFT) & ddp->idx_mask;
	if (idx < ddp->nppods) {
		struct cxgb3i_gather_list *gl = ddp->gl_map[idx];
		unsigned int npods;

		if (!gl || !gl->nelem) {
			ddp_log_error("release 0x%x, idx 0x%x, gl 0x%p, %u.\n",
				      tag, idx, gl, gl ? gl->nelem : 0);
			return;
		}
		npods = (gl->nelem + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
		ddp_log_debug("ddp tag 0x%x, release idx 0x%x, npods %u.\n",
			      tag, idx, npods);
		clear_ddp_map(ddp, tag, idx, npods);
		ddp_unmark_entries(ddp, idx, npods);
		cxgb3i_ddp_release_gl(gl, ddp->pdev);
	} else
		ddp_log_error("ddp tag 0x%x, idx 0x%x > max 0x%x.\n",
			      tag, idx, ddp->nppods);
}

static int setup_conn_pgidx(struct t3cdev *tdev, unsigned int tid, int pg_idx,
			    int reply)
{
	struct sk_buff *skb = alloc_skb(sizeof(struct cpl_set_tcb_field),
					GFP_KERNEL);
	struct cpl_set_tcb_field *req;
	u64 val = pg_idx < DDP_PGIDX_MAX ? pg_idx : 0;

	if (!skb)
		return -ENOMEM;

	/* set up ulp submode and page size */
	req = (struct cpl_set_tcb_field *)skb_put(skb, sizeof(*req));
	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
	req->reply = V_NO_REPLY(reply ? 0 : 1);
	req->cpu_idx = 0;
	req->word = htons(31);
	req->mask = cpu_to_be64(0xF0000000);
	req->val = cpu_to_be64(val << 28);
	skb->priority = CPL_PRIORITY_CONTROL;

	cxgb3_ofld_send(tdev, skb);
	return 0;
}

/**
 * cxgb3i_setup_conn_host_pagesize - setup the conn.'s ddp page size
 * @tdev: t3cdev adapter
 * @tid: connection id
 * @reply: request reply from h/w
 * set up the ddp page size based on the host PAGE_SIZE for a connection
 * identified by tid
 */
int cxgb3i_setup_conn_host_pagesize(struct t3cdev *tdev, unsigned int tid,
				    int reply)
{
	return setup_conn_pgidx(tdev, tid, page_idx, reply);
}

/**
 * cxgb3i_setup_conn_pagesize - setup the conn.'s ddp page size
 * @tdev: t3cdev adapter
 * @tid: connection id
 * @reply: request reply from h/w
 * @pgsz: ddp page size
 * set up the ddp page size for a connection identified by tid
 */
int cxgb3i_setup_conn_pagesize(struct t3cdev *tdev, unsigned int tid,
				int reply, unsigned long pgsz)
{
	int pgidx = cxgb3i_ddp_find_page_index(pgsz);

	return setup_conn_pgidx(tdev, tid, pgidx, reply);
}

/**
 * cxgb3i_setup_conn_digest - setup conn. digest setting
 * @tdev: t3cdev adapter
 * @tid: connection id
 * @hcrc: header digest enabled
 * @dcrc: data digest enabled
 * @reply: request reply from h/w
 * set up the iscsi digest settings for a connection identified by tid
 */
int cxgb3i_setup_conn_digest(struct t3cdev *tdev, unsigned int tid,
			     int hcrc, int dcrc, int reply)
{
	struct sk_buff *skb = alloc_skb(sizeof(struct cpl_set_tcb_field),
					GFP_KERNEL);
	struct cpl_set_tcb_field *req;
	u64 val = (hcrc ? 1 : 0) | (dcrc ? 2 : 0);

	if (!skb)
		return -ENOMEM;

	/* set up ulp submode and page size */
	req = (struct cpl_set_tcb_field *)skb_put(skb, sizeof(*req));
	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
	req->reply = V_NO_REPLY(reply ? 0 : 1);
	req->cpu_idx = 0;
	req->word = htons(31);
	req->mask = cpu_to_be64(0x0F000000);
	req->val = cpu_to_be64(val << 24);
	skb->priority = CPL_PRIORITY_CONTROL;

	cxgb3_ofld_send(tdev, skb);
	return 0;
}


/**
 * cxgb3i_adapter_ddp_info - read the adapter's ddp information
 * @tdev: t3cdev adapter
 * @tformat: tag format
 * @txsz: max tx pdu payload size, filled in by this func.
 * @rxsz: max rx pdu payload size, filled in by this func.
 * setup the tag format for a given iscsi entity
 */
int cxgb3i_adapter_ddp_info(struct t3cdev *tdev,
			    struct cxgb3i_tag_format *tformat,
			    unsigned int *txsz, unsigned int *rxsz)
{
	struct cxgb3i_ddp_info *ddp;
	unsigned char idx_bits;

	if (!tformat)
		return -EINVAL;

	if (!tdev->ulp_iscsi)
		return -EINVAL;

	ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;

	idx_bits = 32 - tformat->sw_bits;
	tformat->rsvd_bits = ddp->idx_bits;
	tformat->rsvd_shift = PPOD_IDX_SHIFT;
	tformat->rsvd_mask = (1 << tformat->rsvd_bits) - 1;

	ddp_log_info("tag format: sw %u, rsvd %u,%u, mask 0x%x.\n",
		      tformat->sw_bits, tformat->rsvd_bits,
		      tformat->rsvd_shift, tformat->rsvd_mask);

	*txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
			ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
	*rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
			ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
	ddp_log_info("max payload size: %u/%u, %u/%u.\n",
		     *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
	return 0;
}

/**
 * cxgb3i_ddp_cleanup - release the cxgb3 adapter's ddp resource
 * @tdev: t3cdev adapter
 * release all the resource held by the ddp pagepod manager for a given
 * adapter if needed
 */
void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
{
	int i = 0;
	struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;

	ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp);

	if (ddp) {
		tdev->ulp_iscsi = NULL;
		while (i < ddp->nppods) {
			struct cxgb3i_gather_list *gl = ddp->gl_map[i];
			if (gl) {
				int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
						>> PPOD_PAGES_SHIFT;
				ddp_log_info("t3dev 0x%p, ddp %d + %d.\n",
						tdev, i, npods);
				kfree(gl);
				ddp_free_gl_skb(ddp, i, npods);
				i += npods;
			} else
				i++;
		}
		cxgb3i_free_big_mem(ddp);
	}
}

/**
 * ddp_init - initialize the cxgb3 adapter's ddp resource
 * @tdev: t3cdev adapter
 * initialize the ddp pagepod manager for a given adapter
 */
static void ddp_init(struct t3cdev *tdev)
{
	struct cxgb3i_ddp_info *ddp;
	struct ulp_iscsi_info uinfo;
	unsigned int ppmax, bits;
	int i, err;

	if (tdev->ulp_iscsi) {
		ddp_log_warn("t3dev 0x%p, ddp 0x%p already set up.\n",
				tdev, tdev->ulp_iscsi);
		return;
	}

	err = tdev->ctl(tdev, ULP_ISCSI_GET_PARAMS, &uinfo);
	if (err < 0) {
		ddp_log_error("%s, failed to get iscsi param err=%d.\n",
				 tdev->name, err);
		return;
	}

	ppmax = (uinfo.ulimit - uinfo.llimit + 1) >> PPOD_SIZE_SHIFT;
	bits = __ilog2_u32(ppmax) + 1;
	if (bits > PPOD_IDX_MAX_SIZE)
		bits = PPOD_IDX_MAX_SIZE;
	ppmax = (1 << (bits - 1)) - 1;

	ddp = cxgb3i_alloc_big_mem(sizeof(struct cxgb3i_ddp_info) +
				   ppmax *
					(sizeof(struct cxgb3i_gather_list *) +
					sizeof(struct sk_buff *)),
				   GFP_KERNEL);
	if (!ddp) {
		ddp_log_warn("%s unable to alloc ddp 0x%d, ddp disabled.\n",
			     tdev->name, ppmax);
		return;
	}
	ddp->gl_map = (struct cxgb3i_gather_list **)(ddp + 1);
	ddp->gl_skb = (struct sk_buff **)(((char *)ddp->gl_map) +
					  ppmax *
					  sizeof(struct cxgb3i_gather_list *));
	spin_lock_init(&ddp->map_lock);

	ddp->tdev = tdev;
	ddp->pdev = uinfo.pdev;
	ddp->max_txsz = min_t(unsigned int, uinfo.max_txsz, ULP2_MAX_PKT_SIZE);
	ddp->max_rxsz = min_t(unsigned int, uinfo.max_rxsz, ULP2_MAX_PKT_SIZE);
	ddp->llimit = uinfo.llimit;
	ddp->ulimit = uinfo.ulimit;
	ddp->nppods = ppmax;
	ddp->idx_last = ppmax;
	ddp->idx_bits = bits;
	ddp->idx_mask = (1 << bits) - 1;
	ddp->rsvd_tag_mask = (1 << (bits + PPOD_IDX_SHIFT)) - 1;

	uinfo.tagmask = ddp->idx_mask << PPOD_IDX_SHIFT;
	for (i = 0; i < DDP_PGIDX_MAX; i++)
		uinfo.pgsz_factor[i] = ddp_page_order[i];
	uinfo.ulimit = uinfo.llimit + (ppmax << PPOD_SIZE_SHIFT);

	err = tdev->ctl(tdev, ULP_ISCSI_SET_PARAMS, &uinfo);
	if (err < 0) {
		ddp_log_warn("%s unable to set iscsi param err=%d, "
			      "ddp disabled.\n", tdev->name, err);
		goto free_ddp_map;
	}

	tdev->ulp_iscsi = ddp;

	ddp_log_info("tdev 0x%p, nppods %u, bits %u, mask 0x%x,0x%x pkt %u/%u,"
			" %u/%u.\n",
			tdev, ppmax, ddp->idx_bits, ddp->idx_mask,
			ddp->rsvd_tag_mask, ddp->max_txsz, uinfo.max_txsz,
			ddp->max_rxsz, uinfo.max_rxsz);
	return;

free_ddp_map:
	cxgb3i_free_big_mem(ddp);
}

/**
 * cxgb3i_ddp_init - initialize ddp functions
 */
void cxgb3i_ddp_init(struct t3cdev *tdev)
{
	if (page_idx == DDP_PGIDX_MAX) {
		page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
		ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n",
				PAGE_SIZE, page_idx);
	}
	ddp_init(tdev);
}
