Commit 5999299f authored by Varun Prakash's avatar Varun Prakash Committed by David S. Miller
Browse files

cxgb3i,cxgb4i,libcxgbi: remove iSCSI DDP support



Remove old ddp code from cxgb3i,cxgb4i,libcxgbi.

Next two commits adds DDP support using
common iSCSI DDP Page Pod Manager.

Signed-off-by: default avatarVarun Prakash <varun@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b8b9d81b
Loading
Loading
Loading
Loading
+0 −128
Original line number Diff line number Diff line
@@ -1076,65 +1076,6 @@ static inline void ulp_mem_io_set_hdr(struct sk_buff *skb, unsigned int addr)
	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 ddp_set_map(struct cxgbi_sock *csk, struct cxgbi_pagepod_hdr *hdr,
			unsigned int idx, unsigned int npods,
				struct cxgbi_gather_list *gl)
{
	struct cxgbi_device *cdev = csk->cdev;
	struct cxgbi_ddp_info *ddp = cdev->ddp;
	unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
	int i;

	log_debug(1 << CXGBI_DBG_DDP,
		"csk 0x%p, idx %u, npods %u, gl 0x%p.\n",
		csk, idx, npods, gl);

	for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
		struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) +
						PPOD_SIZE, 0, GFP_ATOMIC);

		if (!skb)
			return -ENOMEM;

		ulp_mem_io_set_hdr(skb, pm_addr);
		cxgbi_ddp_ppod_set((struct cxgbi_pagepod *)(skb->head +
					sizeof(struct ulp_mem_io)),
				   hdr, gl, i * PPOD_PAGES_MAX);
		skb->priority = CPL_PRIORITY_CONTROL;
		cxgb3_ofld_send(cdev->lldev, skb);
	}
	return 0;
}

static void ddp_clear_map(struct cxgbi_hba *chba, unsigned int tag,
			  unsigned int idx, unsigned int npods)
{
	struct cxgbi_device *cdev = chba->cdev;
	struct cxgbi_ddp_info *ddp = cdev->ddp;
	unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
	int i;

	log_debug(1 << CXGBI_DBG_DDP,
		"cdev 0x%p, idx %u, npods %u, tag 0x%x.\n",
		cdev, idx, npods, tag);

	for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
		struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) +
						PPOD_SIZE, 0, GFP_ATOMIC);

		if (!skb) {
			pr_err("tag 0x%x, 0x%x, %d/%u, skb OOM.\n",
				tag, idx, i, npods);
			continue;
		}
		ulp_mem_io_set_hdr(skb, pm_addr);
		skb->priority = CPL_PRIORITY_CONTROL;
		cxgb3_ofld_send(cdev->lldev, skb);
	}
}

static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk,
@@ -1202,23 +1143,6 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
	return 0;
}

/**
 * t3_ddp_cleanup - release the cxgb3 adapter's ddp resource
 * @cdev: cxgb3i adapter
 * release all the resource held by the ddp pagepod manager for a given
 * adapter if needed
 */

static void t3_ddp_cleanup(struct cxgbi_device *cdev)
{
	struct t3cdev *tdev = (struct t3cdev *)cdev->lldev;

	if (cxgbi_ddp_cleanup(cdev)) {
		pr_info("t3dev 0x%p, ulp_iscsi no more user.\n", tdev);
		tdev->ulp_iscsi = NULL;
	}
}

/**
 * ddp_init - initialize the cxgb3 adapter's ddp resource
 * @cdev: cxgb3i adapter
@@ -1226,59 +1150,8 @@ static void t3_ddp_cleanup(struct cxgbi_device *cdev)
 */
static int cxgb3i_ddp_init(struct cxgbi_device *cdev)
{
	struct t3cdev *tdev = (struct t3cdev *)cdev->lldev;
	struct cxgbi_ddp_info *ddp = tdev->ulp_iscsi;
	struct ulp_iscsi_info uinfo;
	unsigned int pgsz_factor[4];
	int i, err;

	if (ddp) {
		kref_get(&ddp->refcnt);
		pr_warn("t3dev 0x%p, ddp 0x%p already set up.\n",
			tdev, tdev->ulp_iscsi);
		cdev->ddp = ddp;
		return -EALREADY;
	}

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

	err = cxgbi_ddp_init(cdev, uinfo.llimit, uinfo.ulimit,
			uinfo.max_txsz, uinfo.max_rxsz);
	if (err < 0)
		return err;

	ddp = cdev->ddp;

	uinfo.tagmask = ddp->idx_mask << PPOD_IDX_SHIFT;
	cxgbi_ddp_page_size_factor(pgsz_factor);
	for (i = 0; i < 4; i++)
		uinfo.pgsz_factor[i] = pgsz_factor[i];
	uinfo.ulimit = uinfo.llimit + (ddp->nppods << PPOD_SIZE_SHIFT);

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

	cdev->csk_ddp_setup_digest = ddp_setup_conn_digest;
	cdev->csk_ddp_setup_pgidx = ddp_setup_conn_pgidx;
	cdev->csk_ddp_set = ddp_set_map;
	cdev->csk_ddp_clear = ddp_clear_map;

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

@@ -1325,7 +1198,6 @@ static void cxgb3i_dev_open(struct t3cdev *t3dev)
	cdev->rx_credit_thres = cxgb3i_rx_credit_thres;
	cdev->skb_tx_rsvd = CXGB3I_TX_HEADER_LEN;
	cdev->skb_rx_extra = sizeof(struct cpl_iscsi_hdr_norss);
	cdev->dev_ddp_cleanup = t3_ddp_cleanup;
	cdev->itp = &cxgb3i_iscsi_transport;

	err = cxgb3i_ddp_init(cdev);
+0 −142
Original line number Diff line number Diff line
@@ -1543,110 +1543,6 @@ int cxgb4i_ofld_init(struct cxgbi_device *cdev)
	return 0;
}

/*
 * functions to program the pagepod in h/w
 */
#define ULPMEM_IDATA_MAX_NPPODS	4 /* 256/PPOD_SIZE */
static inline void ulp_mem_io_set_hdr(struct cxgb4_lld_info *lldi,
				struct ulp_mem_io *req,
				unsigned int wr_len, unsigned int dlen,
				unsigned int pm_addr)
{
	struct ulptx_idata *idata = (struct ulptx_idata *)(req + 1);

	INIT_ULPTX_WR(req, wr_len, 0, 0);
	if (is_t4(lldi->adapter_type))
		req->cmd = htonl(ULPTX_CMD_V(ULP_TX_MEM_WRITE) |
					(ULP_MEMIO_ORDER_F));
	else
		req->cmd = htonl(ULPTX_CMD_V(ULP_TX_MEM_WRITE) |
					(T5_ULP_MEMIO_IMM_F));
	req->dlen = htonl(ULP_MEMIO_DATA_LEN_V(dlen >> 5));
	req->lock_addr = htonl(ULP_MEMIO_ADDR_V(pm_addr >> 5));
	req->len16 = htonl(DIV_ROUND_UP(wr_len - sizeof(req->wr), 16));

	idata->cmd_more = htonl(ULPTX_CMD_V(ULP_TX_SC_IMM));
	idata->len = htonl(dlen);
}

static int ddp_ppod_write_idata(struct cxgbi_device *cdev, unsigned int port_id,
				struct cxgbi_pagepod_hdr *hdr, unsigned int idx,
				unsigned int npods,
				struct cxgbi_gather_list *gl,
				unsigned int gl_pidx)
{
	struct cxgbi_ddp_info *ddp = cdev->ddp;
	struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
	struct sk_buff *skb;
	struct ulp_mem_io *req;
	struct ulptx_idata *idata;
	struct cxgbi_pagepod *ppod;
	unsigned int pm_addr = idx * PPOD_SIZE + ddp->llimit;
	unsigned int dlen = PPOD_SIZE * npods;
	unsigned int wr_len = roundup(sizeof(struct ulp_mem_io) +
				sizeof(struct ulptx_idata) + dlen, 16);
	unsigned int i;

	skb = alloc_wr(wr_len, 0, GFP_ATOMIC);
	if (!skb) {
		pr_err("cdev 0x%p, idx %u, npods %u, OOM.\n",
			cdev, idx, npods);
		return -ENOMEM;
	}
	req = (struct ulp_mem_io *)skb->head;
	set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);

	ulp_mem_io_set_hdr(lldi, req, wr_len, dlen, pm_addr);
	idata = (struct ulptx_idata *)(req + 1);
	ppod = (struct cxgbi_pagepod *)(idata + 1);

	for (i = 0; i < npods; i++, ppod++, gl_pidx += PPOD_PAGES_MAX) {
		if (!hdr && !gl)
			cxgbi_ddp_ppod_clear(ppod);
		else
			cxgbi_ddp_ppod_set(ppod, hdr, gl, gl_pidx);
	}

	cxgb4_ofld_send(cdev->ports[port_id], skb);
	return 0;
}

static int ddp_set_map(struct cxgbi_sock *csk, struct cxgbi_pagepod_hdr *hdr,
			unsigned int idx, unsigned int npods,
			struct cxgbi_gather_list *gl)
{
	unsigned int i, cnt;
	int err = 0;

	for (i = 0; i < npods; i += cnt, idx += cnt) {
		cnt = npods - i;
		if (cnt > ULPMEM_IDATA_MAX_NPPODS)
			cnt = ULPMEM_IDATA_MAX_NPPODS;
		err = ddp_ppod_write_idata(csk->cdev, csk->port_id, hdr,
					idx, cnt, gl, 4 * i);
		if (err < 0)
			break;
	}
	return err;
}

static void ddp_clear_map(struct cxgbi_hba *chba, unsigned int tag,
			  unsigned int idx, unsigned int npods)
{
	unsigned int i, cnt;
	int err;

	for (i = 0; i < npods; i += cnt, idx += cnt) {
		cnt = npods - i;
		if (cnt > ULPMEM_IDATA_MAX_NPPODS)
			cnt = ULPMEM_IDATA_MAX_NPPODS;
		err = ddp_ppod_write_idata(chba->cdev, chba->port_id, NULL,
					idx, cnt, NULL, 0);
		if (err < 0)
			break;
	}
}

static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, unsigned int tid,
				int pg_idx, bool reply)
{
@@ -1712,46 +1608,8 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,

static int cxgb4i_ddp_init(struct cxgbi_device *cdev)
{
	struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
	struct cxgbi_ddp_info *ddp = cdev->ddp;
	unsigned int tagmask, pgsz_factor[4];
	int err;

	if (ddp) {
		kref_get(&ddp->refcnt);
		pr_warn("cdev 0x%p, ddp 0x%p already set up.\n",
			cdev, cdev->ddp);
		return -EALREADY;
	}

	err = cxgbi_ddp_init(cdev, lldi->vr->iscsi.start,
			lldi->vr->iscsi.start + lldi->vr->iscsi.size - 1,
			lldi->iscsi_iolen, lldi->iscsi_iolen);
	if (err < 0)
		return err;

	ddp = cdev->ddp;

	tagmask = ddp->idx_mask << PPOD_IDX_SHIFT;
	cxgbi_ddp_page_size_factor(pgsz_factor);
	cxgb4_iscsi_init(lldi->ports[0], tagmask, pgsz_factor);

	cdev->csk_ddp_setup_digest = ddp_setup_conn_digest;
	cdev->csk_ddp_setup_pgidx = ddp_setup_conn_pgidx;
	cdev->csk_ddp_set = ddp_set_map;
	cdev->csk_ddp_clear = ddp_clear_map;

	pr_info("cxgb4i 0x%p tag: sw %u, rsvd %u,%u, mask 0x%x.\n",
		cdev, cdev->tag_format.sw_bits, cdev->tag_format.rsvd_bits,
		cdev->tag_format.rsvd_shift, cdev->tag_format.rsvd_mask);
	pr_info("cxgb4i 0x%p, nppods %u, bits %u, mask 0x%x,0x%x pkt %u/%u, "
		" %u/%u.\n",
		cdev, ddp->nppods, ddp->idx_bits, ddp->idx_mask,
		ddp->rsvd_tag_mask, ddp->max_txsz, lldi->iscsi_iolen,
		ddp->max_rxsz, lldi->iscsi_iolen);
	pr_info("cxgb4i 0x%p max payload size: %u/%u, %u/%u.\n",
		cdev, cdev->tx_max_size, ddp->max_txsz, cdev->rx_max_size,
		ddp->max_rxsz);
	return 0;
}

+0 −578

File changed.

Preview size limit exceeded, changes collapsed.

+0 −161
Original line number Diff line number Diff line
@@ -84,91 +84,12 @@ static inline unsigned int cxgbi_ulp_extra_len(int submode)
	return ulp2_extra_len[submode & 3];
}

/*
 * struct pagepod_hdr, pagepod - pagepod format
 */

#define CPL_RX_DDP_STATUS_DDP_SHIFT	16 /* ddp'able */
#define CPL_RX_DDP_STATUS_PAD_SHIFT	19 /* pad error */
#define CPL_RX_DDP_STATUS_HCRC_SHIFT	20 /* hcrc error */
#define CPL_RX_DDP_STATUS_DCRC_SHIFT	21 /* dcrc error */

struct cxgbi_pagepod_hdr {
	u32 vld_tid;
	u32 pgsz_tag_clr;
	u32 max_offset;
	u32 page_offset;
	u64 rsvd;
};

#define PPOD_PAGES_MAX			4
struct cxgbi_pagepod {
	struct cxgbi_pagepod_hdr hdr;
	u64 addr[PPOD_PAGES_MAX + 1];
};

struct cxgbi_tag_format {
	unsigned char sw_bits;
	unsigned char rsvd_bits;
	unsigned char rsvd_shift;
	unsigned char filler[1];
	u32 rsvd_mask;
};

struct cxgbi_gather_list {
	unsigned int tag;
	unsigned int length;
	unsigned int offset;
	unsigned int nelem;
	struct page **pages;
	dma_addr_t phys_addr[0];
};

struct cxgbi_ddp_info {
	struct kref refcnt;
	struct cxgbi_device *cdev;
	struct pci_dev *pdev;
	unsigned int max_txsz;
	unsigned int max_rxsz;
	unsigned int llimit;
	unsigned int ulimit;
	unsigned int nppods;
	unsigned int idx_last;
	unsigned char idx_bits;
	unsigned char filler[3];
	unsigned int idx_mask;
	unsigned int rsvd_tag_mask;
	spinlock_t map_lock;
	struct cxgbi_gather_list **gl_map;
};

#define DDP_PGIDX_MAX		4
#define DDP_THRESHOLD		2048

#define PPOD_PAGES_SHIFT	2       /*  4 pages per pod */

#define PPOD_SIZE               sizeof(struct cxgbi_pagepod)  /*  64 */
#define PPOD_SIZE_SHIFT         6

#define ULPMEM_DSGL_MAX_NPPODS	16	/*  1024/PPOD_SIZE */
#define ULPMEM_IDATA_MAX_NPPODS	4	/*  256/PPOD_SIZE */
#define PCIE_MEMWIN_MAX_NPPODS	16	/*  1024/PPOD_SIZE */

#define PPOD_COLOR_SHIFT	0
#define PPOD_COLOR(x)		((x) << PPOD_COLOR_SHIFT)

#define PPOD_IDX_SHIFT          6
#define PPOD_IDX_MAX_SIZE       24

#define PPOD_TID_SHIFT		0
#define PPOD_TID(x)		((x) << PPOD_TID_SHIFT)

#define PPOD_TAG_SHIFT		6
#define PPOD_TAG(x)		((x) << PPOD_TAG_SHIFT)

#define PPOD_VALID_SHIFT	24
#define PPOD_VALID(x)		((x) << PPOD_VALID_SHIFT)
#define PPOD_VALID_FLAG		PPOD_VALID(1U)

/*
 * sge_opaque_hdr -
@@ -548,15 +469,8 @@ struct cxgbi_device {
	unsigned int tx_max_size;
	unsigned int rx_max_size;
	struct cxgbi_ports_map pmap;
	struct cxgbi_tag_format tag_format;
	struct cxgbi_ddp_info *ddp;

	void (*dev_ddp_cleanup)(struct cxgbi_device *);
	int (*csk_ddp_set)(struct cxgbi_sock *, struct cxgbi_pagepod_hdr *,
				unsigned int, unsigned int,
				struct cxgbi_gather_list *);
	void (*csk_ddp_clear)(struct cxgbi_hba *,
				unsigned int, unsigned int, unsigned int);
	int (*csk_ddp_setup_digest)(struct cxgbi_sock *,
				unsigned int, int, int, int);
	int (*csk_ddp_setup_pgidx)(struct cxgbi_sock *,
@@ -600,78 +514,6 @@ struct cxgbi_task_data {
#define iscsi_task_cxgbi_data(task) \
	((task)->dd_data + sizeof(struct iscsi_tcp_task))

static inline int cxgbi_is_ddp_tag(struct cxgbi_tag_format *tformat, u32 tag)
{
	return !(tag & (1 << (tformat->rsvd_bits + tformat->rsvd_shift - 1)));
}

static inline int cxgbi_sw_tag_usable(struct cxgbi_tag_format *tformat,
					u32 sw_tag)
{
	sw_tag >>= (32 - tformat->rsvd_bits);
	return !sw_tag;
}

static inline u32 cxgbi_set_non_ddp_tag(struct cxgbi_tag_format *tformat,
					u32 sw_tag)
{
	unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1;
	u32 mask = (1 << shift) - 1;

	if (sw_tag && (sw_tag & ~mask)) {
		u32 v1 = sw_tag & ((1 << shift) - 1);
		u32 v2 = (sw_tag >> (shift - 1)) << shift;

		return v2 | v1 | 1 << shift;
	}

	return sw_tag | 1 << shift;
}

static inline u32 cxgbi_ddp_tag_base(struct cxgbi_tag_format *tformat,
					u32 sw_tag)
{
	u32 mask = (1 << tformat->rsvd_shift) - 1;

	if (sw_tag && (sw_tag & ~mask)) {
		u32 v1 = sw_tag & mask;
		u32 v2 = sw_tag >> tformat->rsvd_shift;

		v2 <<= tformat->rsvd_bits + tformat->rsvd_shift;

		return v2 | v1;
	}

	return sw_tag;
}

static inline u32 cxgbi_tag_rsvd_bits(struct cxgbi_tag_format *tformat,
					u32 tag)
{
	if (cxgbi_is_ddp_tag(tformat, tag))
		return (tag >> tformat->rsvd_shift) & tformat->rsvd_mask;

	return 0;
}

static inline u32 cxgbi_tag_nonrsvd_bits(struct cxgbi_tag_format *tformat,
					u32 tag)
{
	unsigned char shift = tformat->rsvd_bits + tformat->rsvd_shift - 1;
	u32 v1, v2;

	if (cxgbi_is_ddp_tag(tformat, tag)) {
		v1 = tag & ((1 << tformat->rsvd_shift) - 1);
		v2 = (tag >> (shift + 1)) << tformat->rsvd_shift;
	} else {
		u32 mask = (1 << shift) - 1;
		tag &= ~(1 << shift);
		v1 = tag & mask;
		v2 = (tag >> 1) & ~mask;
	}
	return v1 | v2;
}

static inline void *cxgbi_alloc_big_mem(unsigned int size,
					gfp_t gfp)
{
@@ -749,7 +591,4 @@ int cxgbi_ddp_init(struct cxgbi_device *, unsigned int, unsigned int,
			unsigned int, unsigned int);
int cxgbi_ddp_cleanup(struct cxgbi_device *);
void cxgbi_ddp_page_size_factor(int *);
void cxgbi_ddp_ppod_clear(struct cxgbi_pagepod *);
void cxgbi_ddp_ppod_set(struct cxgbi_pagepod *, struct cxgbi_pagepod_hdr *,
			struct cxgbi_gather_list *, unsigned int);
#endif	/*__LIBCXGBI_H__*/