aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-10 01:22:44 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-16 07:03:18 -0400
commite53e97ce3c7119199d2788d8fd1618efa9c2d1eb (patch)
tree799f1b7960fcaf9a02800419b038d42eb031f776 /include/asm-sparc64
parent8f41958bdd577731f7411c9605cfaa9db6766809 (diff)
[SPARC64]: Add LDOM virtual channel driver and VIO device layer.
Virtual devices on Sun Logical Domains are built on top of a virtual channel framework. This, with help of hypervisor interfaces, provides a link layer protocol with basic handshaking over which virtual device clients and servers communicate. Built on top of this is a VIO device protocol which has it's own handshaking and message types. At this layer attributes are exchanged (disk size, network device addresses, etc.) descriptor rings are registered, and data transfers are triggers and replied to. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/asm-sparc64')
-rw-r--r--include/asm-sparc64/ldc.h136
-rw-r--r--include/asm-sparc64/vio.h402
2 files changed, 538 insertions, 0 deletions
diff --git a/include/asm-sparc64/ldc.h b/include/asm-sparc64/ldc.h
new file mode 100644
index 000000000000..24fd2367d33a
--- /dev/null
+++ b/include/asm-sparc64/ldc.h
@@ -0,0 +1,136 @@
1#ifndef _SPARC64_LDC_H
2#define _SPARC64_LDC_H
3
4#include <asm/hypervisor.h>
5
6extern int ldom_domaining_enabled;
7
8/* The event handler will be evoked when link state changes
9 * or data becomes available on the receive side.
10 *
11 * For non-RAW links, if the LDC_EVENT_RESET event arrives the
12 * driver should reset all of it's internal state and reinvoke
13 * ldc_connect() to try and bring the link up again.
14 *
15 * For RAW links, ldc_connect() is not used. Instead the driver
16 * just waits for the LDC_EVENT_UP event.
17 */
18struct ldc_channel_config {
19 void (*event)(void *arg, int event);
20
21 u32 mtu;
22 unsigned int rx_irq;
23 unsigned int tx_irq;
24 u8 mode;
25#define LDC_MODE_RAW 0x00
26#define LDC_MODE_UNRELIABLE 0x01
27#define LDC_MODE_RESERVED 0x02
28#define LDC_MODE_RELIABLE 0x03
29#define LDC_MODE_STREAM 0x04
30
31 u8 debug;
32#define LDC_DEBUG_HS 0x01
33#define LDC_DEBUG_STATE 0x02
34#define LDC_DEBUG_RX 0x04
35#define LDC_DEBUG_TX 0x08
36#define LDC_DEBUG_DATA 0x10
37};
38
39#define LDC_EVENT_RESET 0x01
40#define LDC_EVENT_UP 0x02
41#define LDC_EVENT_DATA_READY 0x04
42
43#define LDC_STATE_INVALID 0x00
44#define LDC_STATE_INIT 0x01
45#define LDC_STATE_BOUND 0x02
46#define LDC_STATE_READY 0x03
47#define LDC_STATE_CONNECTED 0x04
48
49struct ldc_channel;
50
51/* Allocate state for a channel. */
52extern struct ldc_channel *ldc_alloc(unsigned long id,
53 const struct ldc_channel_config *cfgp,
54 void *event_arg);
55
56/* Shut down and free state for a channel. */
57extern void ldc_free(struct ldc_channel *lp);
58
59/* Register TX and RX queues of the link with the hypervisor. */
60extern int ldc_bind(struct ldc_channel *lp);
61
62/* For non-RAW protocols we need to complete a handshake before
63 * communication can proceed. ldc_connect() does that, if the
64 * handshake completes successfully, an LDC_EVENT_UP event will
65 * be sent up to the driver.
66 */
67extern int ldc_connect(struct ldc_channel *lp);
68extern int ldc_disconnect(struct ldc_channel *lp);
69
70extern int ldc_state(struct ldc_channel *lp);
71
72/* Read and write operations. Only valid when the link is up. */
73extern int ldc_write(struct ldc_channel *lp, const void *buf,
74 unsigned int size);
75extern int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size);
76
77#define LDC_MAP_SHADOW 0x01
78#define LDC_MAP_DIRECT 0x02
79#define LDC_MAP_IO 0x04
80#define LDC_MAP_R 0x08
81#define LDC_MAP_W 0x10
82#define LDC_MAP_X 0x20
83#define LDC_MAP_RW (LDC_MAP_R | LDC_MAP_W)
84#define LDC_MAP_RWX (LDC_MAP_R | LDC_MAP_W | LDC_MAP_X)
85#define LDC_MAP_ALL 0x03f
86
87struct ldc_trans_cookie {
88 u64 cookie_addr;
89 u64 cookie_size;
90};
91
92struct scatterlist;
93extern int ldc_map_sg(struct ldc_channel *lp,
94 struct scatterlist *sg, int num_sg,
95 struct ldc_trans_cookie *cookies, int ncookies,
96 unsigned int map_perm);
97
98extern int ldc_map_single(struct ldc_channel *lp,
99 void *buf, unsigned int len,
100 struct ldc_trans_cookie *cookies, int ncookies,
101 unsigned int map_perm);
102
103extern void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies,
104 int ncookies);
105
106extern int ldc_copy(struct ldc_channel *lp, int copy_dir,
107 void *buf, unsigned int len, unsigned long offset,
108 struct ldc_trans_cookie *cookies, int ncookies);
109
110static inline int ldc_get_dring_entry(struct ldc_channel *lp,
111 void *buf, unsigned int len,
112 unsigned long offset,
113 struct ldc_trans_cookie *cookies,
114 int ncookies)
115{
116 return ldc_copy(lp, LDC_COPY_IN, buf, len, offset, cookies, ncookies);
117}
118
119static inline int ldc_put_dring_entry(struct ldc_channel *lp,
120 void *buf, unsigned int len,
121 unsigned long offset,
122 struct ldc_trans_cookie *cookies,
123 int ncookies)
124{
125 return ldc_copy(lp, LDC_COPY_OUT, buf, len, offset, cookies, ncookies);
126}
127
128extern void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len,
129 struct ldc_trans_cookie *cookies,
130 int *ncookies, unsigned int map_perm);
131
132extern void ldc_free_exp_dring(struct ldc_channel *lp, void *buf,
133 unsigned int len,
134 struct ldc_trans_cookie *cookies, int ncookies);
135
136#endif /* _SPARC64_LDC_H */
diff --git a/include/asm-sparc64/vio.h b/include/asm-sparc64/vio.h
new file mode 100644
index 000000000000..47c3da76dcb8
--- /dev/null
+++ b/include/asm-sparc64/vio.h
@@ -0,0 +1,402 @@
1#ifndef _SPARC64_VIO_H
2#define _SPARC64_VIO_H
3
4#include <linux/kernel.h>
5#include <linux/device.h>
6#include <linux/mod_devicetable.h>
7#include <linux/timer.h>
8#include <linux/spinlock.h>
9#include <linux/completion.h>
10#include <linux/list.h>
11
12#include <asm/ldc.h>
13#include <asm/mdesc.h>
14
15struct vio_msg_tag {
16 u8 type;
17#define VIO_TYPE_CTRL 0x01
18#define VIO_TYPE_DATA 0x02
19#define VIO_TYPE_ERR 0x04
20
21 u8 stype;
22#define VIO_SUBTYPE_INFO 0x01
23#define VIO_SUBTYPE_ACK 0x02
24#define VIO_SUBTYPE_NACK 0x04
25
26 u16 stype_env;
27#define VIO_VER_INFO 0x0001
28#define VIO_ATTR_INFO 0x0002
29#define VIO_DRING_REG 0x0003
30#define VIO_DRING_UNREG 0x0004
31#define VIO_RDX 0x0005
32#define VIO_PKT_DATA 0x0040
33#define VIO_DESC_DATA 0x0041
34#define VIO_DRING_DATA 0x0042
35#define VNET_MCAST_INFO 0x0101
36
37 u32 sid;
38};
39
40struct vio_rdx {
41 struct vio_msg_tag tag;
42 u64 resv[6];
43};
44
45struct vio_ver_info {
46 struct vio_msg_tag tag;
47 u16 major;
48 u16 minor;
49 u8 dev_class;
50#define VDEV_NETWORK 0x01
51#define VDEV_NETWORK_SWITCH 0x02
52#define VDEV_DISK 0x03
53#define VDEV_DISK_SERVER 0x04
54
55 u8 resv1[3];
56 u64 resv2[5];
57};
58
59struct vio_dring_register {
60 struct vio_msg_tag tag;
61 u64 dring_ident;
62 u32 num_descr;
63 u32 descr_size;
64 u16 options;
65#define VIO_TX_DRING 0x0001
66#define VIO_RX_DRING 0x0002
67 u16 resv;
68 u32 num_cookies;
69 struct ldc_trans_cookie cookies[0];
70};
71
72struct vio_dring_unregister {
73 struct vio_msg_tag tag;
74 u64 dring_ident;
75 u64 resv[5];
76};
77
78/* Data transfer modes */
79#define VIO_PKT_MODE 0x01 /* Packet based transfer */
80#define VIO_DESC_MODE 0x02 /* In-band descriptors */
81#define VIO_DRING_MODE 0x03 /* Descriptor rings */
82
83struct vio_dring_data {
84 struct vio_msg_tag tag;
85 u64 seq;
86 u64 dring_ident;
87 u32 start_idx;
88 u32 end_idx;
89 u8 state;
90#define VIO_DRING_ACTIVE 0x01
91#define VIO_DRING_STOPPED 0x02
92
93 u8 __pad1;
94 u16 __pad2;
95 u32 __pad3;
96 u64 __par4[2];
97};
98
99struct vio_dring_hdr {
100 u8 state;
101#define VIO_DESC_FREE 0x01
102#define VIO_DESC_READY 0x02
103#define VIO_DESC_ACCEPTED 0x03
104#define VIO_DESC_DONE 0x04
105 u8 ack;
106#define VIO_ACK_ENABLE 0x01
107#define VIO_ACK_DISABLE 0x00
108
109 u16 __pad1;
110 u32 __pad2;
111};
112
113/* VIO disk specific structures and defines */
114struct vio_disk_attr_info {
115 struct vio_msg_tag tag;
116 u8 xfer_mode;
117 u8 vdisk_type;
118#define VD_DISK_TYPE_SLICE 0x01 /* Slice in block device */
119#define VD_DISK_TYPE_DISK 0x02 /* Entire block device */
120 u16 resv1;
121 u32 vdisk_block_size;
122 u64 operations;
123 u64 vdisk_size;
124 u64 max_xfer_size;
125 u64 resv2[2];
126};
127
128struct vio_disk_desc {
129 struct vio_dring_hdr hdr;
130 u64 req_id;
131 u8 operation;
132#define VD_OP_BREAD 0x01 /* Block read */
133#define VD_OP_BWRITE 0x02 /* Block write */
134#define VD_OP_FLUSH 0x03 /* Flush disk contents */
135#define VD_OP_GET_WCE 0x04 /* Get write-cache status */
136#define VD_OP_SET_WCE 0x05 /* Enable/disable write-cache */
137#define VD_OP_GET_VTOC 0x06 /* Get VTOC */
138#define VD_OP_SET_VTOC 0x07 /* Set VTOC */
139#define VD_OP_GET_DISKGEOM 0x08 /* Get disk geometry */
140#define VD_OP_SET_DISKGEOM 0x09 /* Set disk geometry */
141#define VD_OP_SCSICMD 0x0a /* SCSI control command */
142#define VD_OP_GET_DEVID 0x0b /* Get device ID */
143#define VD_OP_GET_EFI 0x0c /* Get EFI */
144#define VD_OP_SET_EFI 0x0d /* Set EFI */
145 u8 slice;
146 u16 resv1;
147 u32 status;
148 u64 offset;
149 u64 size;
150 u32 ncookies;
151 u32 resv2;
152 struct ldc_trans_cookie cookies[0];
153};
154
155#define VIO_DISK_VNAME_LEN 8
156#define VIO_DISK_ALABEL_LEN 128
157#define VIO_DISK_NUM_PART 8
158
159struct vio_disk_vtoc {
160 u8 volume_name[VIO_DISK_VNAME_LEN];
161 u16 sector_size;
162 u16 num_partitions;
163 u8 ascii_label[VIO_DISK_ALABEL_LEN];
164 struct {
165 u16 id;
166 u16 perm_flags;
167 u32 resv;
168 u64 start_block;
169 u64 num_blocks;
170 } partitions[VIO_DISK_NUM_PART];
171};
172
173struct vio_disk_geom {
174 u16 num_cyl; /* Num data cylinders */
175 u16 alt_cyl; /* Num alternate cylinders */
176 u16 beg_cyl; /* Cyl off of fixed head area */
177 u16 num_hd; /* Num heads */
178 u16 num_sec; /* Num sectors */
179 u16 ifact; /* Interleave factor */
180 u16 apc; /* Alts per cylinder (SCSI) */
181 u16 rpm; /* Revolutions per minute */
182 u16 phy_cyl; /* Num physical cylinders */
183 u16 wr_skip; /* Num sects to skip, writes */
184 u16 rd_skip; /* Num sects to skip, writes */
185};
186
187struct vio_disk_devid {
188 u16 resv;
189 u16 type;
190 u32 len;
191 char id[0];
192};
193
194struct vio_disk_efi {
195 u64 lba;
196 u64 len;
197 char data[0];
198};
199
200/* VIO net specific structures and defines */
201struct vio_net_attr_info {
202 struct vio_msg_tag tag;
203 u8 xfer_mode;
204 u8 addr_type;
205#define VNET_ADDR_ETHERMAC 0x01
206 u16 ack_freq;
207 u32 resv1;
208 u64 addr;
209 u64 mtu;
210 u64 resv2[3];
211};
212
213#define VNET_NUM_MCAST 7
214
215struct vio_net_mcast_info {
216 struct vio_msg_tag tag;
217 u8 set;
218 u8 count;
219 u8 mcast_addr[VNET_NUM_MCAST * 6];
220 u32 resv;
221};
222
223struct vio_net_desc {
224 struct vio_dring_hdr hdr;
225 u32 size;
226 u32 ncookies;
227 struct ldc_trans_cookie cookies[0];
228};
229
230#define VIO_MAX_RING_COOKIES 24
231
232struct vio_dring_state {
233 u64 ident;
234 void *base;
235 u64 snd_nxt;
236 u64 rcv_nxt;
237 u32 entry_size;
238 u32 num_entries;
239 u32 prod;
240 u32 cons;
241 u32 pending;
242 int ncookies;
243 struct ldc_trans_cookie cookies[VIO_MAX_RING_COOKIES];
244};
245
246static inline void *vio_dring_cur(struct vio_dring_state *dr)
247{
248 return dr->base + (dr->entry_size * dr->prod);
249}
250
251static inline void *vio_dring_entry(struct vio_dring_state *dr,
252 unsigned int index)
253{
254 return dr->base + (dr->entry_size * index);
255}
256
257static inline u32 vio_dring_avail(struct vio_dring_state *dr,
258 unsigned int ring_size)
259{
260 /* Ensure build-time power-of-2. */
261 BUILD_BUG_ON(ring_size & (ring_size - 1));
262
263 return (dr->pending -
264 ((dr->prod - dr->cons) & (ring_size - 1)));
265}
266
267struct vio_dev {
268 struct mdesc_node *mp;
269 struct device_node *dp;
270
271 const char *type;
272 const char *compat;
273 int compat_len;
274
275 struct device dev;
276};
277
278struct vio_driver {
279 struct list_head node;
280 const struct vio_device_id *id_table;
281 int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
282 int (*remove)(struct vio_dev *dev);
283 void (*shutdown)(struct vio_dev *dev);
284 unsigned long driver_data;
285 struct device_driver driver;
286};
287
288struct vio_version {
289 u16 major;
290 u16 minor;
291};
292
293struct vio_driver_state;
294struct vio_driver_ops {
295 int (*send_attr)(struct vio_driver_state *vio);
296 int (*handle_attr)(struct vio_driver_state *vio, void *pkt);
297 void (*handshake_complete)(struct vio_driver_state *vio);
298};
299
300struct vio_completion {
301 struct completion com;
302 int err;
303 int waiting_for;
304};
305
306struct vio_driver_state {
307 /* Protects VIO handshake and, optionally, driver private state. */
308 spinlock_t lock;
309
310 struct ldc_channel *lp;
311
312 u32 _peer_sid;
313 u32 _local_sid;
314 struct vio_dring_state drings[2];
315#define VIO_DRIVER_TX_RING 0
316#define VIO_DRIVER_RX_RING 1
317
318 u8 hs_state;
319#define VIO_HS_INVALID 0x00
320#define VIO_HS_GOTVERS 0x01
321#define VIO_HS_GOT_ATTR 0x04
322#define VIO_HS_SENT_DREG 0x08
323#define VIO_HS_SENT_RDX 0x10
324#define VIO_HS_GOT_RDX_ACK 0x20
325#define VIO_HS_GOT_RDX 0x40
326#define VIO_HS_SENT_RDX_ACK 0x80
327#define VIO_HS_COMPLETE (VIO_HS_GOT_RDX_ACK | VIO_HS_SENT_RDX_ACK)
328
329 u8 dev_class;
330
331 u8 dr_state;
332#define VIO_DR_STATE_TXREG 0x01
333#define VIO_DR_STATE_RXREG 0x02
334#define VIO_DR_STATE_TXREQ 0x10
335#define VIO_DR_STATE_RXREQ 0x20
336
337 u8 debug;
338#define VIO_DEBUG_HS 0x01
339#define VIO_DEBUG_DATA 0x02
340
341 void *desc_buf;
342 unsigned int desc_buf_len;
343
344 struct vio_completion *cmp;
345
346 struct vio_dev *vdev;
347
348 unsigned long channel_id;
349 unsigned int tx_irq;
350 unsigned int rx_irq;
351
352 struct timer_list timer;
353
354 struct vio_version ver;
355
356 struct mdesc_node *endpoint;
357
358 struct vio_version *ver_table;
359 int ver_table_entries;
360
361 char *name;
362
363 struct vio_driver_ops *ops;
364};
365
366#define viodbg(TYPE, f, a...) \
367do { if (vio->debug & VIO_DEBUG_##TYPE) \
368 printk(KERN_INFO "vio: ID[%lu] " f, vio->channel_id, ## a); \
369} while (0)
370
371extern int vio_register_driver(struct vio_driver *drv);
372extern void vio_unregister_driver(struct vio_driver *drv);
373
374static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
375{
376 return container_of(drv, struct vio_driver, driver);
377}
378
379static inline struct vio_dev *to_vio_dev(struct device *dev)
380{
381 return container_of(dev, struct vio_dev, dev);
382}
383
384extern int vio_ldc_send(struct vio_driver_state *vio, void *data, int len);
385extern void vio_link_state_change(struct vio_driver_state *vio, int event);
386extern void vio_conn_reset(struct vio_driver_state *vio);
387extern int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt);
388extern int vio_validate_sid(struct vio_driver_state *vio,
389 struct vio_msg_tag *tp);
390extern u32 vio_send_sid(struct vio_driver_state *vio);
391extern int vio_ldc_alloc(struct vio_driver_state *vio,
392 struct ldc_channel_config *base_cfg, void *event_arg);
393extern void vio_ldc_free(struct vio_driver_state *vio);
394extern int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
395 u8 dev_class, struct mdesc_node *channel_endpoint,
396 struct vio_version *ver_table, int ver_table_size,
397 struct vio_driver_ops *ops, char *name);
398
399extern struct mdesc_node *vio_find_endpoint(struct vio_dev *vdev);
400extern void vio_port_up(struct vio_driver_state *vio);
401
402#endif /* _SPARC64_VIO_H */