162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _SPARC64_LDC_H 362306a36Sopenharmony_ci#define _SPARC64_LDC_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <asm/hypervisor.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ciextern int ldom_domaining_enabled; 862306a36Sopenharmony_civoid ldom_set_var(const char *var, const char *value); 962306a36Sopenharmony_civoid ldom_reboot(const char *boot_command); 1062306a36Sopenharmony_civoid ldom_power_off(void); 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* The event handler will be evoked when link state changes 1362306a36Sopenharmony_ci * or data becomes available on the receive side. 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci * For non-RAW links, if the LDC_EVENT_RESET event arrives the 1662306a36Sopenharmony_ci * driver should reset all of it's internal state and reinvoke 1762306a36Sopenharmony_ci * ldc_connect() to try and bring the link up again. 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * For RAW links, ldc_connect() is not used. Instead the driver 2062306a36Sopenharmony_ci * just waits for the LDC_EVENT_UP event. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_cistruct ldc_channel_config { 2362306a36Sopenharmony_ci void (*event)(void *arg, int event); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci u32 mtu; 2662306a36Sopenharmony_ci unsigned int rx_irq; 2762306a36Sopenharmony_ci unsigned int tx_irq; 2862306a36Sopenharmony_ci u8 mode; 2962306a36Sopenharmony_ci#define LDC_MODE_RAW 0x00 3062306a36Sopenharmony_ci#define LDC_MODE_UNRELIABLE 0x01 3162306a36Sopenharmony_ci#define LDC_MODE_RESERVED 0x02 3262306a36Sopenharmony_ci#define LDC_MODE_STREAM 0x03 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci u8 debug; 3562306a36Sopenharmony_ci#define LDC_DEBUG_HS 0x01 3662306a36Sopenharmony_ci#define LDC_DEBUG_STATE 0x02 3762306a36Sopenharmony_ci#define LDC_DEBUG_RX 0x04 3862306a36Sopenharmony_ci#define LDC_DEBUG_TX 0x08 3962306a36Sopenharmony_ci#define LDC_DEBUG_DATA 0x10 4062306a36Sopenharmony_ci}; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define LDC_EVENT_RESET 0x01 4362306a36Sopenharmony_ci#define LDC_EVENT_UP 0x02 4462306a36Sopenharmony_ci#define LDC_EVENT_DATA_READY 0x04 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define LDC_STATE_INVALID 0x00 4762306a36Sopenharmony_ci#define LDC_STATE_INIT 0x01 4862306a36Sopenharmony_ci#define LDC_STATE_BOUND 0x02 4962306a36Sopenharmony_ci#define LDC_STATE_READY 0x03 5062306a36Sopenharmony_ci#define LDC_STATE_CONNECTED 0x04 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define LDC_PACKET_SIZE 64 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistruct ldc_channel; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* Allocate state for a channel. */ 5762306a36Sopenharmony_cistruct ldc_channel *ldc_alloc(unsigned long id, 5862306a36Sopenharmony_ci const struct ldc_channel_config *cfgp, 5962306a36Sopenharmony_ci void *event_arg, 6062306a36Sopenharmony_ci const char *name); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* Shut down and free state for a channel. */ 6362306a36Sopenharmony_civoid ldc_free(struct ldc_channel *lp); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/* Register TX and RX queues of the link with the hypervisor. */ 6662306a36Sopenharmony_ciint ldc_bind(struct ldc_channel *lp); 6762306a36Sopenharmony_civoid ldc_unbind(struct ldc_channel *lp); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* For non-RAW protocols we need to complete a handshake before 7062306a36Sopenharmony_ci * communication can proceed. ldc_connect() does that, if the 7162306a36Sopenharmony_ci * handshake completes successfully, an LDC_EVENT_UP event will 7262306a36Sopenharmony_ci * be sent up to the driver. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_ciint ldc_connect(struct ldc_channel *lp); 7562306a36Sopenharmony_ciint ldc_disconnect(struct ldc_channel *lp); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ciint ldc_state(struct ldc_channel *lp); 7862306a36Sopenharmony_civoid ldc_set_state(struct ldc_channel *lp, u8 state); 7962306a36Sopenharmony_ciint ldc_mode(struct ldc_channel *lp); 8062306a36Sopenharmony_civoid __ldc_print(struct ldc_channel *lp, const char *caller); 8162306a36Sopenharmony_ciint ldc_rx_reset(struct ldc_channel *lp); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define ldc_print(chan) __ldc_print(chan, __func__) 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/* Read and write operations. Only valid when the link is up. */ 8662306a36Sopenharmony_ciint ldc_write(struct ldc_channel *lp, const void *buf, 8762306a36Sopenharmony_ci unsigned int size); 8862306a36Sopenharmony_ciint ldc_read(struct ldc_channel *lp, void *buf, unsigned int size); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci#define LDC_MAP_SHADOW 0x01 9162306a36Sopenharmony_ci#define LDC_MAP_DIRECT 0x02 9262306a36Sopenharmony_ci#define LDC_MAP_IO 0x04 9362306a36Sopenharmony_ci#define LDC_MAP_R 0x08 9462306a36Sopenharmony_ci#define LDC_MAP_W 0x10 9562306a36Sopenharmony_ci#define LDC_MAP_X 0x20 9662306a36Sopenharmony_ci#define LDC_MAP_RW (LDC_MAP_R | LDC_MAP_W) 9762306a36Sopenharmony_ci#define LDC_MAP_RWX (LDC_MAP_R | LDC_MAP_W | LDC_MAP_X) 9862306a36Sopenharmony_ci#define LDC_MAP_ALL 0x03f 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistruct ldc_trans_cookie { 10162306a36Sopenharmony_ci u64 cookie_addr; 10262306a36Sopenharmony_ci u64 cookie_size; 10362306a36Sopenharmony_ci}; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistruct scatterlist; 10662306a36Sopenharmony_ciint ldc_map_sg(struct ldc_channel *lp, 10762306a36Sopenharmony_ci struct scatterlist *sg, int num_sg, 10862306a36Sopenharmony_ci struct ldc_trans_cookie *cookies, int ncookies, 10962306a36Sopenharmony_ci unsigned int map_perm); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciint ldc_map_single(struct ldc_channel *lp, 11262306a36Sopenharmony_ci void *buf, unsigned int len, 11362306a36Sopenharmony_ci struct ldc_trans_cookie *cookies, int ncookies, 11462306a36Sopenharmony_ci unsigned int map_perm); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_civoid ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies, 11762306a36Sopenharmony_ci int ncookies); 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ciint ldc_copy(struct ldc_channel *lp, int copy_dir, 12062306a36Sopenharmony_ci void *buf, unsigned int len, unsigned long offset, 12162306a36Sopenharmony_ci struct ldc_trans_cookie *cookies, int ncookies); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cistatic inline int ldc_get_dring_entry(struct ldc_channel *lp, 12462306a36Sopenharmony_ci void *buf, unsigned int len, 12562306a36Sopenharmony_ci unsigned long offset, 12662306a36Sopenharmony_ci struct ldc_trans_cookie *cookies, 12762306a36Sopenharmony_ci int ncookies) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci return ldc_copy(lp, LDC_COPY_IN, buf, len, offset, cookies, ncookies); 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic inline int ldc_put_dring_entry(struct ldc_channel *lp, 13362306a36Sopenharmony_ci void *buf, unsigned int len, 13462306a36Sopenharmony_ci unsigned long offset, 13562306a36Sopenharmony_ci struct ldc_trans_cookie *cookies, 13662306a36Sopenharmony_ci int ncookies) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci return ldc_copy(lp, LDC_COPY_OUT, buf, len, offset, cookies, ncookies); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_civoid *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len, 14262306a36Sopenharmony_ci struct ldc_trans_cookie *cookies, 14362306a36Sopenharmony_ci int *ncookies, unsigned int map_perm); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_civoid ldc_free_exp_dring(struct ldc_channel *lp, void *buf, 14662306a36Sopenharmony_ci unsigned int len, 14762306a36Sopenharmony_ci struct ldc_trans_cookie *cookies, int ncookies); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci#endif /* _SPARC64_LDC_H */ 150