summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64/dev/ldcvar.h
blob: bf7a9ed7f1162c7a5299758fd99ebc7ae0f42e0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*	$OpenBSD: ldcvar.h,v 1.4 2009/12/26 21:21:10 kettenis Exp $	*/
/*
 * Copyright (c) 2009 Mark Kettenis
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * LDC queues.
 */

struct ldc_queue {
	bus_dmamap_t	lq_map;
	bus_dma_segment_t lq_seg;
	caddr_t		lq_va;
	int		lq_nentries;
};

struct ldc_queue *ldc_queue_alloc(bus_dma_tag_t, int);
void	ldc_queue_free(bus_dma_tag_t, struct ldc_queue *);

/*
 * LDC virtual link layer protocol.
 */

#define LDC_VERSION_MAJOR	1
#define LDC_VERSION_MINOR	0

#define LDC_PKT_PAYLOAD		56

struct ldc_pkt {
	uint8_t		type;
	uint8_t		stype;
	uint8_t		ctrl;
	uint8_t		env;
	uint32_t	seqid;

	uint16_t	major;
	uint16_t	minor;
	uint32_t	_reserved[13];
};

/* Packet types. */
#define LDC_CTRL	0x01
#define LDC_DATA	0x02
#define LDC_ERR		0x10

/* Packet subtypes. */
#define LDC_INFO	0x01
#define LDC_ACK		0x02
#define LDC_NACK	0x04

/* Control info values. */
#define LDC_VERS	0x01
#define LDC_RTS		0x02
#define LDC_RTR		0x03
#define LDC_RDX		0x04

/* Packet envelope. */
#define LDC_MODE_RAW		0x00
#define LDC_MODE_UNRELIABLE	0x01
#define LDC_MODE_RELIABLE	0x03

#define LDC_LEN_MASK	0x3f
#define LDC_FRAG_MASK	0xc0
#define LDC_FRAG_START	0x40
#define LDC_FRAG_STOP	0x80

/*
 * XXX Get rid of the +8 once we no longer need to store the header of
 * the first packet.
 */
#define LDC_MSG_MAX	(128 + 8)

struct ldc_conn {
	uint64_t	lc_id;

	struct ldc_queue *lc_txq;
	struct ldc_queue *lc_rxq;
	uint64_t	lc_tx_state;
	uint64_t	lc_rx_state;

	uint32_t	lc_tx_seqid;
	uint8_t		lc_state;
#define LDC_SND_VERS	1
#define LDC_RCV_VERS	2
#define LDC_SND_RTS	3
#define LDC_SND_RTR	4
#define LDC_SND_RDX	5

	uint64_t	lc_msg[LDC_MSG_MAX / 8];
	size_t		lc_len;

	void		*lc_sc;
	void		(*lc_reset)(struct ldc_conn *);
	void		(*lc_start)(struct ldc_conn *);
	void		(*lc_rx_data)(struct ldc_conn *, struct ldc_pkt *);
};

void	ldc_rx_ctrl(struct ldc_conn *, struct ldc_pkt *);
void	ldc_rx_data(struct ldc_conn *, struct ldc_pkt *);

void	ldc_send_vers(struct ldc_conn *);

void	ldc_reset(struct ldc_conn *);

/*
 * LDC map tables.
 */

struct ldc_map_slot {
	uint64_t	entry;
	uint64_t	cookie;
};

#define LDC_MTE_R	0x0000000000000010ULL
#define LDC_MTE_W	0x0000000000000020ULL
#define LDC_MTE_X	0x0000000000000040ULL
#define LDC_MTE_IOR	0x0000000000000080ULL
#define LDC_MTE_IOW	0x0000000000000100ULL
#define LDC_MTE_CPR	0x0000000000000200ULL
#define LDC_MTE_CPW	0x0000000000000400ULL
#define LDC_MTE_RA_MASK	0x007fffffffffe000ULL

struct ldc_map {
	bus_dmamap_t		lm_map;
	bus_dma_segment_t	lm_seg;
	struct ldc_map_slot	*lm_slot;
	int			lm_nentries;
	int			lm_next;
	int			lm_count;
};

struct ldc_map *ldc_map_alloc(bus_dma_tag_t, int);
void	ldc_map_free(bus_dma_tag_t, struct ldc_map *);

struct ldc_cookie {
	uint64_t	addr;
	uint64_t	size;
};