diff options
Diffstat (limited to 'include/asm-sparc64/vio.h')
-rw-r--r-- | include/asm-sparc64/vio.h | 404 |
1 files changed, 404 insertions, 0 deletions
diff --git a/include/asm-sparc64/vio.h b/include/asm-sparc64/vio.h new file mode 100644 index 000000000000..83c96422e9d6 --- /dev/null +++ b/include/asm-sparc64/vio.h | |||
@@ -0,0 +1,404 @@ | |||
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 | |||
15 | struct 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 | |||
40 | struct vio_rdx { | ||
41 | struct vio_msg_tag tag; | ||
42 | u64 resv[6]; | ||
43 | }; | ||
44 | |||
45 | struct 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 | |||
59 | struct 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 | |||
72 | struct 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 | |||
83 | struct 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 | |||
99 | struct 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 */ | ||
114 | struct 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 | |||
128 | struct 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 | |||
159 | struct 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 | |||
173 | struct 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 | |||
187 | struct vio_disk_devid { | ||
188 | u16 resv; | ||
189 | u16 type; | ||
190 | u32 len; | ||
191 | char id[0]; | ||
192 | }; | ||
193 | |||
194 | struct vio_disk_efi { | ||
195 | u64 lba; | ||
196 | u64 len; | ||
197 | char data[0]; | ||
198 | }; | ||
199 | |||
200 | /* VIO net specific structures and defines */ | ||
201 | struct 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 | |||
215 | struct 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 | |||
223 | struct 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 | |||
232 | struct 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 | |||
246 | static inline void *vio_dring_cur(struct vio_dring_state *dr) | ||
247 | { | ||
248 | return dr->base + (dr->entry_size * dr->prod); | ||
249 | } | ||
250 | |||
251 | static 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 | |||
257 | static 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 | |||
267 | #define VIO_MAX_TYPE_LEN 64 | ||
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 | unsigned long channel_id; | ||
279 | |||
280 | unsigned int tx_irq; | ||
281 | unsigned int rx_irq; | ||
282 | |||
283 | struct device dev; | ||
284 | }; | ||
285 | |||
286 | struct vio_driver { | ||
287 | struct list_head node; | ||
288 | const struct vio_device_id *id_table; | ||
289 | int (*probe)(struct vio_dev *dev, const struct vio_device_id *id); | ||
290 | int (*remove)(struct vio_dev *dev); | ||
291 | void (*shutdown)(struct vio_dev *dev); | ||
292 | unsigned long driver_data; | ||
293 | struct device_driver driver; | ||
294 | }; | ||
295 | |||
296 | struct vio_version { | ||
297 | u16 major; | ||
298 | u16 minor; | ||
299 | }; | ||
300 | |||
301 | struct vio_driver_state; | ||
302 | struct vio_driver_ops { | ||
303 | int (*send_attr)(struct vio_driver_state *vio); | ||
304 | int (*handle_attr)(struct vio_driver_state *vio, void *pkt); | ||
305 | void (*handshake_complete)(struct vio_driver_state *vio); | ||
306 | }; | ||
307 | |||
308 | struct vio_completion { | ||
309 | struct completion com; | ||
310 | int err; | ||
311 | int waiting_for; | ||
312 | }; | ||
313 | |||
314 | struct vio_driver_state { | ||
315 | /* Protects VIO handshake and, optionally, driver private state. */ | ||
316 | spinlock_t lock; | ||
317 | |||
318 | struct ldc_channel *lp; | ||
319 | |||
320 | u32 _peer_sid; | ||
321 | u32 _local_sid; | ||
322 | struct vio_dring_state drings[2]; | ||
323 | #define VIO_DRIVER_TX_RING 0 | ||
324 | #define VIO_DRIVER_RX_RING 1 | ||
325 | |||
326 | u8 hs_state; | ||
327 | #define VIO_HS_INVALID 0x00 | ||
328 | #define VIO_HS_GOTVERS 0x01 | ||
329 | #define VIO_HS_GOT_ATTR 0x04 | ||
330 | #define VIO_HS_SENT_DREG 0x08 | ||
331 | #define VIO_HS_SENT_RDX 0x10 | ||
332 | #define VIO_HS_GOT_RDX_ACK 0x20 | ||
333 | #define VIO_HS_GOT_RDX 0x40 | ||
334 | #define VIO_HS_SENT_RDX_ACK 0x80 | ||
335 | #define VIO_HS_COMPLETE (VIO_HS_GOT_RDX_ACK | VIO_HS_SENT_RDX_ACK) | ||
336 | |||
337 | u8 dev_class; | ||
338 | |||
339 | u8 dr_state; | ||
340 | #define VIO_DR_STATE_TXREG 0x01 | ||
341 | #define VIO_DR_STATE_RXREG 0x02 | ||
342 | #define VIO_DR_STATE_TXREQ 0x10 | ||
343 | #define VIO_DR_STATE_RXREQ 0x20 | ||
344 | |||
345 | u8 debug; | ||
346 | #define VIO_DEBUG_HS 0x01 | ||
347 | #define VIO_DEBUG_DATA 0x02 | ||
348 | |||
349 | void *desc_buf; | ||
350 | unsigned int desc_buf_len; | ||
351 | |||
352 | struct vio_completion *cmp; | ||
353 | |||
354 | struct vio_dev *vdev; | ||
355 | |||
356 | struct timer_list timer; | ||
357 | |||
358 | struct vio_version ver; | ||
359 | |||
360 | struct vio_version *ver_table; | ||
361 | int ver_table_entries; | ||
362 | |||
363 | char *name; | ||
364 | |||
365 | struct vio_driver_ops *ops; | ||
366 | }; | ||
367 | |||
368 | #define viodbg(TYPE, f, a...) \ | ||
369 | do { if (vio->debug & VIO_DEBUG_##TYPE) \ | ||
370 | printk(KERN_INFO "vio: ID[%lu] " f, \ | ||
371 | vio->vdev->channel_id, ## a); \ | ||
372 | } while (0) | ||
373 | |||
374 | extern int vio_register_driver(struct vio_driver *drv); | ||
375 | extern void vio_unregister_driver(struct vio_driver *drv); | ||
376 | |||
377 | static inline struct vio_driver *to_vio_driver(struct device_driver *drv) | ||
378 | { | ||
379 | return container_of(drv, struct vio_driver, driver); | ||
380 | } | ||
381 | |||
382 | static inline struct vio_dev *to_vio_dev(struct device *dev) | ||
383 | { | ||
384 | return container_of(dev, struct vio_dev, dev); | ||
385 | } | ||
386 | |||
387 | extern int vio_ldc_send(struct vio_driver_state *vio, void *data, int len); | ||
388 | extern void vio_link_state_change(struct vio_driver_state *vio, int event); | ||
389 | extern void vio_conn_reset(struct vio_driver_state *vio); | ||
390 | extern int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt); | ||
391 | extern int vio_validate_sid(struct vio_driver_state *vio, | ||
392 | struct vio_msg_tag *tp); | ||
393 | extern u32 vio_send_sid(struct vio_driver_state *vio); | ||
394 | extern int vio_ldc_alloc(struct vio_driver_state *vio, | ||
395 | struct ldc_channel_config *base_cfg, void *event_arg); | ||
396 | extern void vio_ldc_free(struct vio_driver_state *vio); | ||
397 | extern int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev, | ||
398 | u8 dev_class, struct vio_version *ver_table, | ||
399 | int ver_table_size, struct vio_driver_ops *ops, | ||
400 | char *name); | ||
401 | |||
402 | extern void vio_port_up(struct vio_driver_state *vio); | ||
403 | |||
404 | #endif /* _SPARC64_VIO_H */ | ||