xref: /titanic_52/usr/src/uts/i86pc/sys/ioat.h (revision eca2601cae391051acb146d28fba04237fe1eb85)
117169044Sbrutus /*
217169044Sbrutus  * CDDL HEADER START
317169044Sbrutus  *
417169044Sbrutus  * The contents of this file are subject to the terms of the
517169044Sbrutus  * Common Development and Distribution License (the "License").
617169044Sbrutus  * You may not use this file except in compliance with the License.
717169044Sbrutus  *
817169044Sbrutus  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
917169044Sbrutus  * or http://www.opensolaris.org/os/licensing.
1017169044Sbrutus  * See the License for the specific language governing permissions
1117169044Sbrutus  * and limitations under the License.
1217169044Sbrutus  *
1317169044Sbrutus  * When distributing Covered Code, include this CDDL HEADER in each
1417169044Sbrutus  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1517169044Sbrutus  * If applicable, add the following below this CDDL HEADER, with the
1617169044Sbrutus  * fields enclosed by brackets "[]" replaced with your own identifying
1717169044Sbrutus  * information: Portions Copyright [yyyy] [name of copyright owner]
1817169044Sbrutus  *
1917169044Sbrutus  * CDDL HEADER END
2017169044Sbrutus  */
2117169044Sbrutus 
2217169044Sbrutus /*
23*eca2601cSRandy Fishel  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2417169044Sbrutus  * Use is subject to license terms.
2517169044Sbrutus  */
2617169044Sbrutus 
2717169044Sbrutus #ifndef _SYS_IOAT_H
2817169044Sbrutus #define	_SYS_IOAT_H
2917169044Sbrutus 
3017169044Sbrutus #ifdef __cplusplus
3117169044Sbrutus extern "C" {
3217169044Sbrutus #endif
3317169044Sbrutus 
3417169044Sbrutus #include <sys/types.h>
3517169044Sbrutus #include <sys/dcopy.h>
3617169044Sbrutus #include <sys/dcopy_device.h>
3717169044Sbrutus 
3817169044Sbrutus 
3917169044Sbrutus /* ioat ioctls */
4017169044Sbrutus #define	IOATIOC			('T'<< 8)
4117169044Sbrutus typedef enum {
4217169044Sbrutus 	IOAT_IOCTL_WRITE_REG	= (IOATIOC | 0x0),
4317169044Sbrutus 	IOAT_IOCTL_READ_REG	= (IOATIOC | 0x1),
4417169044Sbrutus 	IOAT_IOCTL_TEST		= (IOATIOC | 0x2)
4517169044Sbrutus } ioat_ioctl_enum_t;
4617169044Sbrutus 
4717169044Sbrutus typedef struct ioat_ioctl_reg_s {
4817169044Sbrutus 	uint_t		size;
4917169044Sbrutus 	uint_t		addr;
5017169044Sbrutus 	uint64_t	data;
5117169044Sbrutus } ioat_ioctl_reg_t;
5217169044Sbrutus typedef ioat_ioctl_reg_t ioat_ioctl_wrreg_t;
5317169044Sbrutus typedef ioat_ioctl_reg_t ioat_ioctl_rdreg_t;
5417169044Sbrutus 
5517169044Sbrutus #ifdef _KERNEL
5617169044Sbrutus /* *** Driver Private Below *** */
5717169044Sbrutus 
5817169044Sbrutus /* IOAT_DMACAPABILITY flags */
5917169044Sbrutus #define	IOAT_DMACAP_PAGEBREAK	0x1
6017169044Sbrutus #define	IOAT_DMACAP_CRC		0x2
6117169044Sbrutus #define	IOAT_DMACAP_MARKERSKIP	0x4
6217169044Sbrutus #define	IOAT_DMACAP_XOR		0x8
6317169044Sbrutus #define	IOAT_DMACAP_DCA		0x10
6417169044Sbrutus 
6517169044Sbrutus /* IOAT_INTRCTL bits */
6617169044Sbrutus #define	IOAT_INTRCTL_MASTER_EN	0x1
6717169044Sbrutus #define	IOAT_INTRCTL_INTR_STAT	0x2
6817169044Sbrutus 
6917169044Sbrutus /* MMIO Registers */
7017169044Sbrutus #define	IOAT_CHANCNT		0x0	/* 8-bit */
7117169044Sbrutus #define	IOAT_XFERCAP		0x1	/* 8-bit */
7217169044Sbrutus #define	IOAT_GENCTRL		0x2	/* 8-bit */
7317169044Sbrutus #define	IOAT_INTRCTL		0x3	/* 8-bit */
7417169044Sbrutus #define	IOAT_ATTNSTATUS		0x4	/* 32-bit */
7517169044Sbrutus #define	IOAT_CBVER		0x8	/* 8-bit */
7617169044Sbrutus #define	IOAT_PERPORT_OFF	0xA	/* 16-bit */
7717169044Sbrutus #define	IOAT_INTRDELAY		0xC	/* 16-bit */
7817169044Sbrutus #define	IOAT_CSSTATUS		0xE	/* 16-bit */
7917169044Sbrutus #define	IOAT_DMACAPABILITY	0x10	/* 32-bit */
8017169044Sbrutus 
8117169044Sbrutus #define	IOAT_CHANNELREG_OFFSET	0x80
8217169044Sbrutus 
8317169044Sbrutus /* Channel Registers */
8417169044Sbrutus #define	IOAT_CHAN_CTL		0x0	/* 16-bit */
8517169044Sbrutus #define	IOAT_CHAN_COMP		0x2	/* 16-bit */
8617169044Sbrutus #define	IOAT_CHAN_CMPL_LO	0x18	/* 32-bit */
8717169044Sbrutus #define	IOAT_CHAN_CMPL_HI	0x1C	/* 32-bit */
8817169044Sbrutus #define	IOAT_CHAN_ERR		0x28	/* 32-bit */
8917169044Sbrutus #define	IOAT_CHAN_ERRMASK	0x2C	/* 32-bit */
9017169044Sbrutus #define	IOAT_CHAN_DCACTRL	0x30	/* 32-bit */
9117169044Sbrutus 
9217169044Sbrutus #define	IOAT_V1_CHAN_STS_LO	0x4	/* 32-bit */
9317169044Sbrutus #define	IOAT_V1_CHAN_STS_HI	0x8	/* 32-bit */
9417169044Sbrutus #define	IOAT_V1_CHAN_ADDR_LO	0x0C	/* 32-bit */
9517169044Sbrutus #define	IOAT_V1_CHAN_ADDR_HI	0x10	/* 32-bit */
9617169044Sbrutus #define	IOAT_V1_CHAN_CMD	0x14	/* 8-bit */
9717169044Sbrutus 
9817169044Sbrutus #define	IOAT_V2_CHAN_CMD	0x4	/* 8-bit */
9917169044Sbrutus #define	IOAT_V2_CHAN_CNT	0x6	/* 16-bit */
10017169044Sbrutus #define	IOAT_V2_CHAN_STS_LO	0x8	/* 32-bit */
10117169044Sbrutus #define	IOAT_V2_CHAN_STS_HI	0xC	/* 32-bit */
10217169044Sbrutus #define	IOAT_V2_CHAN_ADDR_LO	0x10	/* 32-bit */
10317169044Sbrutus #define	IOAT_V2_CHAN_ADDR_HI	0x14	/* 32-bit */
10417169044Sbrutus 
10517169044Sbrutus #define	IOAT_CHAN_STS_ADDR_MASK		0xFFFFFFFFFFFFFFC0
10617169044Sbrutus #define	IOAT_CHAN_STS_XFER_MASK		0x3F
10717169044Sbrutus #define	IOAT_CHAN_STS_FAIL_MASK		0x6
10817169044Sbrutus #define	IOAT_CMPL_INDEX(channel)	\
10917169044Sbrutus 	(((*channel->ic_cmpl & IOAT_CHAN_STS_ADDR_MASK) - \
11017169044Sbrutus 	ring->cr_phys_desc) >> 6)
11117169044Sbrutus #define	IOAT_CMPL_FAILED(channel)	\
11217169044Sbrutus 	(*channel->ic_cmpl & IOAT_CHAN_STS_FAIL_MASK)
11317169044Sbrutus 
11417169044Sbrutus 
11517169044Sbrutus typedef struct ioat_chan_desc_s {
11617169044Sbrutus 	uint32_t	dd_res0;
11717169044Sbrutus 	uint32_t	dd_ctrl;
11817169044Sbrutus 	uint64_t	dd_res1;
11917169044Sbrutus 	uint64_t	dd_res2;
12017169044Sbrutus 	uint64_t	dd_next_desc;
12117169044Sbrutus 	uint64_t	dd_res4;
12217169044Sbrutus 	uint64_t	dd_res5;
12317169044Sbrutus 	uint64_t	dd_res6;
12417169044Sbrutus 	uint64_t	dd_res7;
12517169044Sbrutus } ioat_chan_desc_t;
12617169044Sbrutus 
12717169044Sbrutus /* dca dd_ctrl bits */
12817169044Sbrutus #define	IOAT_DESC_CTRL_OP_CNTX	((uint32_t)0xFF << 24)
12917169044Sbrutus #define	IOAT_DESC_CTRL_CNTX_CHNG	0x1
13017169044Sbrutus typedef struct ioat_chan_dca_desc_s {
13117169044Sbrutus 	uint32_t	dd_cntx;
13217169044Sbrutus 	uint32_t	dd_ctrl;
13317169044Sbrutus 	uint64_t	dd_res1;
13417169044Sbrutus 	uint64_t	dd_res2;
13517169044Sbrutus 	uint64_t	dd_next_desc;
13617169044Sbrutus 	uint64_t	dd_res4;
13717169044Sbrutus 	uint64_t	dd_res5;
13817169044Sbrutus 	uint64_t	dd_res6;
13917169044Sbrutus 	uint64_t	dd_res7;
14017169044Sbrutus } ioat_chan_dca_desc_t;
14117169044Sbrutus 
14217169044Sbrutus /* dma dd_ctrl bits */
14317169044Sbrutus #define	IOAT_DESC_CTRL_OP_DMA	(0x0 << 24)
14417169044Sbrutus #define	IOAT_DESC_DMACTRL_NULL	0x20
14517169044Sbrutus #define	IOAT_DESC_CTRL_FENCE	0x10
14617169044Sbrutus #define	IOAT_DESC_CTRL_CMPL	0x8
147*eca2601cSRandy Fishel #define	IOAT_DESC_CTRL_NODSTSNP	0x4
148*eca2601cSRandy Fishel #define	IOAT_DESC_CTRL_NOSRCSNP	0x2
14917169044Sbrutus #define	IOAT_DESC_CTRL_INTR	0x1
15017169044Sbrutus typedef struct ioat_chan_dma_desc_s {
15117169044Sbrutus 	uint32_t	dd_size;
15217169044Sbrutus 	uint32_t	dd_ctrl;
15317169044Sbrutus 	uint64_t	dd_src_paddr;
15417169044Sbrutus 	uint64_t	dd_dest_paddr;
15517169044Sbrutus 	uint64_t	dd_next_desc;
15617169044Sbrutus 	uint64_t	dd_next_src_paddr;	/* v2 only */
15717169044Sbrutus 	uint64_t	dd_next_dest_paddr;	/* v2 only */
15817169044Sbrutus 	uint64_t	dd_res6;
15917169044Sbrutus 	uint64_t	dd_res7;
16017169044Sbrutus } ioat_chan_dma_desc_t;
16117169044Sbrutus 
16217169044Sbrutus 
16317169044Sbrutus typedef enum {
16417169044Sbrutus 	IOAT_CBv1,
16517169044Sbrutus 	IOAT_CBv2
16617169044Sbrutus } ioat_version_t;
16717169044Sbrutus 
16817169044Sbrutus /* ioat private data per command */
16917169044Sbrutus typedef struct ioat_cmd_private_s {
17017169044Sbrutus 	uint64_t	ip_generation;
17117169044Sbrutus 	uint64_t	ip_index;
172*eca2601cSRandy Fishel 	uint64_t	ip_start;
17317169044Sbrutus 	dcopy_cmd_t	ip_next;
17417169044Sbrutus } ioat_cmd_private_t;
17517169044Sbrutus 
17617169044Sbrutus /* descriptor ring state */
17717169044Sbrutus typedef struct ioat_channel_ring_s {
17817169044Sbrutus 	/* protects cr_cmpl_gen & cr_cmpl_last */
17917169044Sbrutus 	kmutex_t		cr_cmpl_mutex;
18017169044Sbrutus 
18117169044Sbrutus 	/* desc ring generation for the last completion we saw */
18217169044Sbrutus 	uint64_t		cr_cmpl_gen;
18317169044Sbrutus 
18417169044Sbrutus 	/* last descriptor index we saw complete */
18517169044Sbrutus 	uint64_t		cr_cmpl_last;
18617169044Sbrutus 
18717169044Sbrutus 	/* protects cr_desc_* */
18817169044Sbrutus 	kmutex_t		cr_desc_mutex;
18917169044Sbrutus 
19017169044Sbrutus 	/*
19117169044Sbrutus 	 * last descriptor posted. used to update its next pointer when we
19217169044Sbrutus 	 * add a new desc. Also used to tack the completion (See comment for
19317169044Sbrutus 	 * cr_desc_gen_prev).
19417169044Sbrutus 	 */
19517169044Sbrutus 	uint64_t		cr_desc_prev;
19617169044Sbrutus 
19717169044Sbrutus 	/* where to put the next descriptor */
19817169044Sbrutus 	uint64_t		cr_desc_next;
19917169044Sbrutus 
20017169044Sbrutus 	/* what the current desc ring generation is */
20117169044Sbrutus 	uint64_t		cr_desc_gen;
20217169044Sbrutus 
20317169044Sbrutus 	/*
20417169044Sbrutus 	 * used during cmd_post to track the last desc posted. cr_desc_next
20517169044Sbrutus 	 * and cr_desc_gen will be pointing to the next free desc after
20617169044Sbrutus 	 * writing the descriptor to the ring. But we want to track the
20717169044Sbrutus 	 * completion for the last descriptor posted.
20817169044Sbrutus 	 */
20917169044Sbrutus 	uint64_t		cr_desc_gen_prev;
21017169044Sbrutus 
21117169044Sbrutus 	/* the last desc in the ring (for wrap) */
21217169044Sbrutus 	uint64_t		cr_desc_last;
21317169044Sbrutus 
21417169044Sbrutus 	/* pointer to the head of the ring */
21517169044Sbrutus 	ioat_chan_desc_t	*cr_desc;
21617169044Sbrutus 
21717169044Sbrutus 	/* physical address of the head of the ring */
21817169044Sbrutus 	uint64_t		cr_phys_desc;
21917169044Sbrutus 
22017169044Sbrutus 	/* back pointer to the channel state */
22117169044Sbrutus 	struct ioat_channel_s	*cr_chan;
22217169044Sbrutus 
22317169044Sbrutus 	/* for CB v2, number of desc posted (written to IOAT_V2_CHAN_CNT) */
22417169044Sbrutus 	uint_t			cr_post_cnt;
22517169044Sbrutus } ioat_channel_ring_t;
22617169044Sbrutus 
22717169044Sbrutus /* track channel state so we can handle a failure */
22817169044Sbrutus typedef enum {
22917169044Sbrutus 	IOAT_CHANNEL_OK = 0,
23017169044Sbrutus 	IOAT_CHANNEL_IN_FAILURE = 1
23117169044Sbrutus } ic_channel_state_t;
23217169044Sbrutus 
23317169044Sbrutus typedef struct ioat_channel_s *ioat_channel_t;
23417169044Sbrutus struct ioat_channel_s {
23517169044Sbrutus 	/* channel's ring state */
23617169044Sbrutus 	ioat_channel_ring_t	*ic_ring;
23717169044Sbrutus 
23817169044Sbrutus 	/* IOAT_CBv1 || IOAT_CBv2 */
23917169044Sbrutus 	ioat_version_t		ic_ver;
24017169044Sbrutus 
24117169044Sbrutus 	/*
24217169044Sbrutus 	 * state to determine if it's OK to post the the channel and if all
24317169044Sbrutus 	 * future polls should return failure.
24417169044Sbrutus 	 */
24517169044Sbrutus 	ic_channel_state_t	ic_channel_state;
24617169044Sbrutus 
24717169044Sbrutus 	/* channel command cache (*_cmd_alloc, *_cmd_free, etc) */
24817169044Sbrutus 	kmem_cache_t		*ic_cmd_cache;
24917169044Sbrutus 
25017169044Sbrutus 	/* dcopy state for dcopy_device_channel_notify() call */
25117169044Sbrutus 	dcopy_handle_t		ic_dcopy_handle;
25217169044Sbrutus 
25317169044Sbrutus 	/* location in memory where completions are DMA'ed into */
25417169044Sbrutus 	volatile uint64_t	*ic_cmpl;
25517169044Sbrutus 
25617169044Sbrutus 	/* channel specific registers */
25717169044Sbrutus 	uint8_t			*ic_regs;
25817169044Sbrutus 
25917169044Sbrutus 	/* if this channel is using DCA */
26017169044Sbrutus 	boolean_t		ic_dca_active;
26117169044Sbrutus 
26217169044Sbrutus 	/* DCA ID the channel is currently pointing to */
26317169044Sbrutus 	uint32_t		ic_dca_current;
26417169044Sbrutus 
26517169044Sbrutus 	/* devices channel number */
26617169044Sbrutus 	uint_t			ic_chan_num;
26717169044Sbrutus 
26817169044Sbrutus 	/* number of descriptors in ring */
26917169044Sbrutus 	uint_t			ic_chan_desc_cnt;
27017169044Sbrutus 
27117169044Sbrutus 	/* descriptor ring alloc state */
27217169044Sbrutus 	ddi_dma_handle_t	ic_desc_dma_handle;
27317169044Sbrutus 	size_t			ic_desc_alloc_size;
27417169044Sbrutus 	ddi_acc_handle_t	ic_desc_handle;
27517169044Sbrutus 	ddi_dma_cookie_t	ic_desc_cookies;
27617169044Sbrutus 
27717169044Sbrutus 	/* completion buffer alloc state */
27817169044Sbrutus 	ddi_dma_handle_t	ic_cmpl_dma_handle;
27917169044Sbrutus 	size_t			ic_cmpl_alloc_size;
28017169044Sbrutus 	ddi_acc_handle_t	ic_cmpl_handle;
28117169044Sbrutus 	ddi_dma_cookie_t	ic_cmpl_cookie;
28217169044Sbrutus 	uint64_t		ic_phys_cmpl;
28317169044Sbrutus 
28417169044Sbrutus 	/* if inuse, we need to re-init the channel during resume */
28517169044Sbrutus 	boolean_t		ic_inuse;
28617169044Sbrutus 
28717169044Sbrutus 	/* backpointer to driver state */
28817169044Sbrutus 	struct ioat_state_s	*ic_state;
28917169044Sbrutus };
29017169044Sbrutus 
29117169044Sbrutus typedef struct ioat_rs_s *ioat_rs_hdl_t;
29217169044Sbrutus 
29317169044Sbrutus /* driver state */
29417169044Sbrutus typedef struct ioat_state_s {
29517169044Sbrutus 	dev_info_t		*is_dip;
29617169044Sbrutus 	int			is_instance;
29717169044Sbrutus 
29817169044Sbrutus 	kmutex_t		is_mutex;
29917169044Sbrutus 
30017169044Sbrutus 	/* register handle and pointer to registers */
30117169044Sbrutus 	ddi_acc_handle_t	is_reg_handle;
30217169044Sbrutus 	uint8_t			*is_genregs;
30317169044Sbrutus 
30417169044Sbrutus 	/* IOAT_CBv1 || IOAT_CBv2 */
30517169044Sbrutus 	ioat_version_t		is_ver;
30617169044Sbrutus 
30717169044Sbrutus 	/* channel state */
30817169044Sbrutus 	ioat_channel_t		is_channel;
30917169044Sbrutus 	size_t			is_chansize;
31017169044Sbrutus 	ioat_rs_hdl_t		is_channel_rs;
31117169044Sbrutus 
31217169044Sbrutus 	ddi_iblock_cookie_t	is_iblock_cookie;
31317169044Sbrutus 
31417169044Sbrutus 	/* device info */
31517169044Sbrutus 	uint_t			is_chanoff;
31617169044Sbrutus 	uint_t			is_num_channels;
31717169044Sbrutus 	uint_t			is_maxxfer;
31817169044Sbrutus 	uint_t			is_cbver;
31917169044Sbrutus 	uint_t			is_intrdelay;
32017169044Sbrutus 	uint_t			is_status;
32117169044Sbrutus 	uint_t			is_capabilities;
32217169044Sbrutus 
32317169044Sbrutus 	/* dcopy_device_register()/dcopy_device_unregister() state */
32417169044Sbrutus 	dcopy_device_handle_t	is_device_handle;
32517169044Sbrutus 	dcopy_device_info_t	is_deviceinfo;
32617169044Sbrutus } ioat_state_t;
32717169044Sbrutus 
32817169044Sbrutus 
32917169044Sbrutus int ioat_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred,
33017169044Sbrutus     int *rval);
33117169044Sbrutus 
33217169044Sbrutus void ioat_rs_init(ioat_state_t *state, uint_t min_val, uint_t max_val,
33317169044Sbrutus     ioat_rs_hdl_t *handle);
33417169044Sbrutus void ioat_rs_fini(ioat_rs_hdl_t *handle);
33517169044Sbrutus int ioat_rs_alloc(ioat_rs_hdl_t handle, uint_t *rs);
33617169044Sbrutus void ioat_rs_free(ioat_rs_hdl_t handle, uint_t rs);
33717169044Sbrutus 
33817169044Sbrutus int ioat_channel_init(ioat_state_t *state);
33917169044Sbrutus void ioat_channel_fini(ioat_state_t *state);
34017169044Sbrutus void ioat_channel_suspend(ioat_state_t *state);
34117169044Sbrutus int ioat_channel_resume(ioat_state_t *state);
34219397407SSherry Moore void ioat_channel_quiesce(ioat_state_t *);
34317169044Sbrutus 
34417169044Sbrutus int ioat_channel_alloc(void *device_private, dcopy_handle_t handle, int flags,
34517169044Sbrutus     uint_t size, dcopy_query_channel_t *info, void *channel_private);
34617169044Sbrutus void ioat_channel_free(void *channel_private);
34717169044Sbrutus void ioat_channel_intr(ioat_channel_t channel);
34817169044Sbrutus int ioat_cmd_alloc(void *channel, int flags, dcopy_cmd_t *cmd);
34917169044Sbrutus void ioat_cmd_free(void *channel, dcopy_cmd_t *cmd);
35017169044Sbrutus int ioat_cmd_post(void *channel, dcopy_cmd_t cmd);
35117169044Sbrutus int ioat_cmd_poll(void *channel, dcopy_cmd_t cmd);
35217169044Sbrutus void ioat_unregister_complete(void *device_private, int status);
35317169044Sbrutus 
35417169044Sbrutus 
35517169044Sbrutus #endif /* _KERNEL */
35617169044Sbrutus 
35717169044Sbrutus #ifdef __cplusplus
35817169044Sbrutus }
35917169044Sbrutus #endif
36017169044Sbrutus 
36117169044Sbrutus #endif /* _SYS_IOAT_H */
362