diff options
Diffstat (limited to 'arch/sparc/include/asm/vio.h')
-rw-r--r-- | arch/sparc/include/asm/vio.h | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h new file mode 100644 index 000000000000..d4de32f0f8af --- /dev/null +++ b/arch/sparc/include/asm/vio.h | |||
@@ -0,0 +1,406 @@ | |||
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 | #include <linux/log2.h> | ||
12 | |||
13 | #include <asm/ldc.h> | ||
14 | #include <asm/mdesc.h> | ||
15 | |||
16 | struct vio_msg_tag { | ||
17 | u8 type; | ||
18 | #define VIO_TYPE_CTRL 0x01 | ||
19 | #define VIO_TYPE_DATA 0x02 | ||
20 | #define VIO_TYPE_ERR 0x04 | ||
21 | |||
22 | u8 stype; | ||
23 | #define VIO_SUBTYPE_INFO 0x01 | ||
24 | #define VIO_SUBTYPE_ACK 0x02 | ||
25 | #define VIO_SUBTYPE_NACK 0x04 | ||
26 | |||
27 | u16 stype_env; | ||
28 | #define VIO_VER_INFO 0x0001 | ||
29 | #define VIO_ATTR_INFO 0x0002 | ||
30 | #define VIO_DRING_REG 0x0003 | ||
31 | #define VIO_DRING_UNREG 0x0004 | ||
32 | #define VIO_RDX 0x0005 | ||
33 | #define VIO_PKT_DATA 0x0040 | ||
34 | #define VIO_DESC_DATA 0x0041 | ||
35 | #define VIO_DRING_DATA 0x0042 | ||
36 | #define VNET_MCAST_INFO 0x0101 | ||
37 | |||
38 | u32 sid; | ||
39 | }; | ||
40 | |||
41 | struct vio_rdx { | ||
42 | struct vio_msg_tag tag; | ||
43 | u64 resv[6]; | ||
44 | }; | ||
45 | |||
46 | struct vio_ver_info { | ||
47 | struct vio_msg_tag tag; | ||
48 | u16 major; | ||
49 | u16 minor; | ||
50 | u8 dev_class; | ||
51 | #define VDEV_NETWORK 0x01 | ||
52 | #define VDEV_NETWORK_SWITCH 0x02 | ||
53 | #define VDEV_DISK 0x03 | ||
54 | #define VDEV_DISK_SERVER 0x04 | ||
55 | |||
56 | u8 resv1[3]; | ||
57 | u64 resv2[5]; | ||
58 | }; | ||
59 | |||
60 | struct vio_dring_register { | ||
61 | struct vio_msg_tag tag; | ||
62 | u64 dring_ident; | ||
63 | u32 num_descr; | ||
64 | u32 descr_size; | ||
65 | u16 options; | ||
66 | #define VIO_TX_DRING 0x0001 | ||
67 | #define VIO_RX_DRING 0x0002 | ||
68 | u16 resv; | ||
69 | u32 num_cookies; | ||
70 | struct ldc_trans_cookie cookies[0]; | ||
71 | }; | ||
72 | |||
73 | struct vio_dring_unregister { | ||
74 | struct vio_msg_tag tag; | ||
75 | u64 dring_ident; | ||
76 | u64 resv[5]; | ||
77 | }; | ||
78 | |||
79 | /* Data transfer modes */ | ||
80 | #define VIO_PKT_MODE 0x01 /* Packet based transfer */ | ||
81 | #define VIO_DESC_MODE 0x02 /* In-band descriptors */ | ||
82 | #define VIO_DRING_MODE 0x03 /* Descriptor rings */ | ||
83 | |||
84 | struct vio_dring_data { | ||
85 | struct vio_msg_tag tag; | ||
86 | u64 seq; | ||
87 | u64 dring_ident; | ||
88 | u32 start_idx; | ||
89 | u32 end_idx; | ||
90 | u8 state; | ||
91 | #define VIO_DRING_ACTIVE 0x01 | ||
92 | #define VIO_DRING_STOPPED 0x02 | ||
93 | |||
94 | u8 __pad1; | ||
95 | u16 __pad2; | ||
96 | u32 __pad3; | ||
97 | u64 __par4[2]; | ||
98 | }; | ||
99 | |||
100 | struct vio_dring_hdr { | ||
101 | u8 state; | ||
102 | #define VIO_DESC_FREE 0x01 | ||
103 | #define VIO_DESC_READY 0x02 | ||
104 | #define VIO_DESC_ACCEPTED 0x03 | ||
105 | #define VIO_DESC_DONE 0x04 | ||
106 | u8 ack; | ||
107 | #define VIO_ACK_ENABLE 0x01 | ||
108 | #define VIO_ACK_DISABLE 0x00 | ||
109 | |||
110 | u16 __pad1; | ||
111 | u32 __pad2; | ||
112 | }; | ||
113 | |||
114 | /* VIO disk specific structures and defines */ | ||
115 | struct vio_disk_attr_info { | ||
116 | struct vio_msg_tag tag; | ||
117 | u8 xfer_mode; | ||
118 | u8 vdisk_type; | ||
119 | #define VD_DISK_TYPE_SLICE 0x01 /* Slice in block device */ | ||
120 | #define VD_DISK_TYPE_DISK 0x02 /* Entire block device */ | ||
121 | u16 resv1; | ||
122 | u32 vdisk_block_size; | ||
123 | u64 operations; | ||
124 | u64 vdisk_size; | ||
125 | u64 max_xfer_size; | ||
126 | u64 resv2[2]; | ||
127 | }; | ||
128 | |||
129 | struct vio_disk_desc { | ||
130 | struct vio_dring_hdr hdr; | ||
131 | u64 req_id; | ||
132 | u8 operation; | ||
133 | #define VD_OP_BREAD 0x01 /* Block read */ | ||
134 | #define VD_OP_BWRITE 0x02 /* Block write */ | ||
135 | #define VD_OP_FLUSH 0x03 /* Flush disk contents */ | ||
136 | #define VD_OP_GET_WCE 0x04 /* Get write-cache status */ | ||
137 | #define VD_OP_SET_WCE 0x05 /* Enable/disable write-cache */ | ||
138 | #define VD_OP_GET_VTOC 0x06 /* Get VTOC */ | ||
139 | #define VD_OP_SET_VTOC 0x07 /* Set VTOC */ | ||
140 | #define VD_OP_GET_DISKGEOM 0x08 /* Get disk geometry */ | ||
141 | #define VD_OP_SET_DISKGEOM 0x09 /* Set disk geometry */ | ||
142 | #define VD_OP_SCSICMD 0x0a /* SCSI control command */ | ||
143 | #define VD_OP_GET_DEVID 0x0b /* Get device ID */ | ||
144 | #define VD_OP_GET_EFI 0x0c /* Get EFI */ | ||
145 | #define VD_OP_SET_EFI 0x0d /* Set EFI */ | ||
146 | u8 slice; | ||
147 | u16 resv1; | ||
148 | u32 status; | ||
149 | u64 offset; | ||
150 | u64 size; | ||
151 | u32 ncookies; | ||
152 | u32 resv2; | ||
153 | struct ldc_trans_cookie cookies[0]; | ||
154 | }; | ||
155 | |||
156 | #define VIO_DISK_VNAME_LEN 8 | ||
157 | #define VIO_DISK_ALABEL_LEN 128 | ||
158 | #define VIO_DISK_NUM_PART 8 | ||
159 | |||
160 | struct vio_disk_vtoc { | ||
161 | u8 volume_name[VIO_DISK_VNAME_LEN]; | ||
162 | u16 sector_size; | ||
163 | u16 num_partitions; | ||
164 | u8 ascii_label[VIO_DISK_ALABEL_LEN]; | ||
165 | struct { | ||
166 | u16 id; | ||
167 | u16 perm_flags; | ||
168 | u32 resv; | ||
169 | u64 start_block; | ||
170 | u64 num_blocks; | ||
171 | } partitions[VIO_DISK_NUM_PART]; | ||
172 | }; | ||
173 | |||
174 | struct vio_disk_geom { | ||
175 | u16 num_cyl; /* Num data cylinders */ | ||
176 | u16 alt_cyl; /* Num alternate cylinders */ | ||
177 | u16 beg_cyl; /* Cyl off of fixed head area */ | ||
178 | u16 num_hd; /* Num heads */ | ||
179 | u16 num_sec; /* Num sectors */ | ||
180 | u16 ifact; /* Interleave factor */ | ||
181 | u16 apc; /* Alts per cylinder (SCSI) */ | ||
182 | u16 rpm; /* Revolutions per minute */ | ||
183 | u16 phy_cyl; /* Num physical cylinders */ | ||
184 | u16 wr_skip; /* Num sects to skip, writes */ | ||
185 | u16 rd_skip; /* Num sects to skip, writes */ | ||
186 | }; | ||
187 | |||
188 | struct vio_disk_devid { | ||
189 | u16 resv; | ||
190 | u16 type; | ||
191 | u32 len; | ||
192 | char id[0]; | ||
193 | }; | ||
194 | |||
195 | struct vio_disk_efi { | ||
196 | u64 lba; | ||
197 | u64 len; | ||
198 | char data[0]; | ||
199 | }; | ||
200 | |||
201 | /* VIO net specific structures and defines */ | ||
202 | struct vio_net_attr_info { | ||
203 | struct vio_msg_tag tag; | ||
204 | u8 xfer_mode; | ||
205 | u8 addr_type; | ||
206 | #define VNET_ADDR_ETHERMAC 0x01 | ||
207 | u16 ack_freq; | ||
208 | u32 resv1; | ||
209 | u64 addr; | ||
210 | u64 mtu; | ||
211 | u64 resv2[3]; | ||
212 | }; | ||
213 | |||
214 | #define VNET_NUM_MCAST 7 | ||
215 | |||
216 | struct vio_net_mcast_info { | ||
217 | struct vio_msg_tag tag; | ||
218 | u8 set; | ||
219 | u8 count; | ||
220 | u8 mcast_addr[VNET_NUM_MCAST * 6]; | ||
221 | u32 resv; | ||
222 | }; | ||
223 | |||
224 | struct vio_net_desc { | ||
225 | struct vio_dring_hdr hdr; | ||
226 | u32 size; | ||
227 | u32 ncookies; | ||
228 | struct ldc_trans_cookie cookies[0]; | ||
229 | }; | ||
230 | |||
231 | #define VIO_MAX_RING_COOKIES 24 | ||
232 | |||
233 | struct vio_dring_state { | ||
234 | u64 ident; | ||
235 | void *base; | ||
236 | u64 snd_nxt; | ||
237 | u64 rcv_nxt; | ||
238 | u32 entry_size; | ||
239 | u32 num_entries; | ||
240 | u32 prod; | ||
241 | u32 cons; | ||
242 | u32 pending; | ||
243 | int ncookies; | ||
244 | struct ldc_trans_cookie cookies[VIO_MAX_RING_COOKIES]; | ||
245 | }; | ||
246 | |||
247 | static inline void *vio_dring_cur(struct vio_dring_state *dr) | ||
248 | { | ||
249 | return dr->base + (dr->entry_size * dr->prod); | ||
250 | } | ||
251 | |||
252 | static inline void *vio_dring_entry(struct vio_dring_state *dr, | ||
253 | unsigned int index) | ||
254 | { | ||
255 | return dr->base + (dr->entry_size * index); | ||
256 | } | ||
257 | |||
258 | static inline u32 vio_dring_avail(struct vio_dring_state *dr, | ||
259 | unsigned int ring_size) | ||
260 | { | ||
261 | BUILD_BUG_ON(!is_power_of_2(ring_size)); | ||
262 | |||
263 | return (dr->pending - | ||
264 | ((dr->prod - dr->cons) & (ring_size - 1))); | ||
265 | } | ||
266 | |||
267 | #define VIO_MAX_TYPE_LEN 32 | ||
268 | #define VIO_MAX_COMPAT_LEN 64 | ||
269 | |||
270 | struct vio_dev { | ||
271 | u64 mp; | ||
272 | struct device_node *dp; | ||
273 | |||
274 | char type[VIO_MAX_TYPE_LEN]; | ||
275 | char compat[VIO_MAX_COMPAT_LEN]; | ||
276 | int compat_len; | ||
277 | |||
278 | u64 dev_no; | ||
279 | |||
280 | unsigned long channel_id; | ||
281 | |||
282 | unsigned int tx_irq; | ||
283 | unsigned int rx_irq; | ||
284 | |||
285 | struct device dev; | ||
286 | }; | ||
287 | |||
288 | struct vio_driver { | ||
289 | struct list_head node; | ||
290 | const struct vio_device_id *id_table; | ||
291 | int (*probe)(struct vio_dev *dev, const struct vio_device_id *id); | ||
292 | int (*remove)(struct vio_dev *dev); | ||
293 | void (*shutdown)(struct vio_dev *dev); | ||
294 | unsigned long driver_data; | ||
295 | struct device_driver driver; | ||
296 | }; | ||
297 | |||
298 | struct vio_version { | ||
299 | u16 major; | ||
300 | u16 minor; | ||
301 | }; | ||
302 | |||
303 | struct vio_driver_state; | ||
304 | struct vio_driver_ops { | ||
305 | int (*send_attr)(struct vio_driver_state *vio); | ||
306 | int (*handle_attr)(struct vio_driver_state *vio, void *pkt); | ||
307 | void (*handshake_complete)(struct vio_driver_state *vio); | ||
308 | }; | ||
309 | |||
310 | struct vio_completion { | ||
311 | struct completion com; | ||
312 | int err; | ||
313 | int waiting_for; | ||
314 | }; | ||
315 | |||
316 | struct vio_driver_state { | ||
317 | /* Protects VIO handshake and, optionally, driver private state. */ | ||
318 | spinlock_t lock; | ||
319 | |||
320 | struct ldc_channel *lp; | ||
321 | |||
322 | u32 _peer_sid; | ||
323 | u32 _local_sid; | ||
324 | struct vio_dring_state drings[2]; | ||
325 | #define VIO_DRIVER_TX_RING 0 | ||
326 | #define VIO_DRIVER_RX_RING 1 | ||
327 | |||
328 | u8 hs_state; | ||
329 | #define VIO_HS_INVALID 0x00 | ||
330 | #define VIO_HS_GOTVERS 0x01 | ||
331 | #define VIO_HS_GOT_ATTR 0x04 | ||
332 | #define VIO_HS_SENT_DREG 0x08 | ||
333 | #define VIO_HS_SENT_RDX 0x10 | ||
334 | #define VIO_HS_GOT_RDX_ACK 0x20 | ||
335 | #define VIO_HS_GOT_RDX 0x40 | ||
336 | #define VIO_HS_SENT_RDX_ACK 0x80 | ||
337 | #define VIO_HS_COMPLETE (VIO_HS_GOT_RDX_ACK | VIO_HS_SENT_RDX_ACK) | ||
338 | |||
339 | u8 dev_class; | ||
340 | |||
341 | u8 dr_state; | ||
342 | #define VIO_DR_STATE_TXREG 0x01 | ||
343 | #define VIO_DR_STATE_RXREG 0x02 | ||
344 | #define VIO_DR_STATE_TXREQ 0x10 | ||
345 | #define VIO_DR_STATE_RXREQ 0x20 | ||
346 | |||
347 | u8 debug; | ||
348 | #define VIO_DEBUG_HS 0x01 | ||
349 | #define VIO_DEBUG_DATA 0x02 | ||
350 | |||
351 | void *desc_buf; | ||
352 | unsigned int desc_buf_len; | ||
353 | |||
354 | struct vio_completion *cmp; | ||
355 | |||
356 | struct vio_dev *vdev; | ||
357 | |||
358 | struct timer_list timer; | ||
359 | |||
360 | struct vio_version ver; | ||
361 | |||
362 | struct vio_version *ver_table; | ||
363 | int ver_table_entries; | ||
364 | |||
365 | char *name; | ||
366 | |||
367 | struct vio_driver_ops *ops; | ||
368 | }; | ||
369 | |||
370 | #define viodbg(TYPE, f, a...) \ | ||
371 | do { if (vio->debug & VIO_DEBUG_##TYPE) \ | ||
372 | printk(KERN_INFO "vio: ID[%lu] " f, \ | ||
373 | vio->vdev->channel_id, ## a); \ | ||
374 | } while (0) | ||
375 | |||
376 | extern int vio_register_driver(struct vio_driver *drv); | ||
377 | extern void vio_unregister_driver(struct vio_driver *drv); | ||
378 | |||
379 | static inline struct vio_driver *to_vio_driver(struct device_driver *drv) | ||
380 | { | ||
381 | return container_of(drv, struct vio_driver, driver); | ||
382 | } | ||
383 | |||
384 | static inline struct vio_dev *to_vio_dev(struct device *dev) | ||
385 | { | ||
386 | return container_of(dev, struct vio_dev, dev); | ||
387 | } | ||
388 | |||
389 | extern int vio_ldc_send(struct vio_driver_state *vio, void *data, int len); | ||
390 | extern void vio_link_state_change(struct vio_driver_state *vio, int event); | ||
391 | extern void vio_conn_reset(struct vio_driver_state *vio); | ||
392 | extern int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt); | ||
393 | extern int vio_validate_sid(struct vio_driver_state *vio, | ||
394 | struct vio_msg_tag *tp); | ||
395 | extern u32 vio_send_sid(struct vio_driver_state *vio); | ||
396 | extern int vio_ldc_alloc(struct vio_driver_state *vio, | ||
397 | struct ldc_channel_config *base_cfg, void *event_arg); | ||
398 | extern void vio_ldc_free(struct vio_driver_state *vio); | ||
399 | extern int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev, | ||
400 | u8 dev_class, struct vio_version *ver_table, | ||
401 | int ver_table_size, struct vio_driver_ops *ops, | ||
402 | char *name); | ||
403 | |||
404 | extern void vio_port_up(struct vio_driver_state *vio); | ||
405 | |||
406 | #endif /* _SPARC64_VIO_H */ | ||