18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _SPARC64_LDC_H 38c2ecf20Sopenharmony_ci#define _SPARC64_LDC_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <asm/hypervisor.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciextern int ldom_domaining_enabled; 88c2ecf20Sopenharmony_civoid ldom_set_var(const char *var, const char *value); 98c2ecf20Sopenharmony_civoid ldom_reboot(const char *boot_command); 108c2ecf20Sopenharmony_civoid ldom_power_off(void); 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* The event handler will be evoked when link state changes 138c2ecf20Sopenharmony_ci * or data becomes available on the receive side. 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * For non-RAW links, if the LDC_EVENT_RESET event arrives the 168c2ecf20Sopenharmony_ci * driver should reset all of it's internal state and reinvoke 178c2ecf20Sopenharmony_ci * ldc_connect() to try and bring the link up again. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * For RAW links, ldc_connect() is not used. Instead the driver 208c2ecf20Sopenharmony_ci * just waits for the LDC_EVENT_UP event. 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_cistruct ldc_channel_config { 238c2ecf20Sopenharmony_ci void (*event)(void *arg, int event); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci u32 mtu; 268c2ecf20Sopenharmony_ci unsigned int rx_irq; 278c2ecf20Sopenharmony_ci unsigned int tx_irq; 288c2ecf20Sopenharmony_ci u8 mode; 298c2ecf20Sopenharmony_ci#define LDC_MODE_RAW 0x00 308c2ecf20Sopenharmony_ci#define LDC_MODE_UNRELIABLE 0x01 318c2ecf20Sopenharmony_ci#define LDC_MODE_RESERVED 0x02 328c2ecf20Sopenharmony_ci#define LDC_MODE_STREAM 0x03 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci u8 debug; 358c2ecf20Sopenharmony_ci#define LDC_DEBUG_HS 0x01 368c2ecf20Sopenharmony_ci#define LDC_DEBUG_STATE 0x02 378c2ecf20Sopenharmony_ci#define LDC_DEBUG_RX 0x04 388c2ecf20Sopenharmony_ci#define LDC_DEBUG_TX 0x08 398c2ecf20Sopenharmony_ci#define LDC_DEBUG_DATA 0x10 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#define LDC_EVENT_RESET 0x01 438c2ecf20Sopenharmony_ci#define LDC_EVENT_UP 0x02 448c2ecf20Sopenharmony_ci#define LDC_EVENT_DATA_READY 0x04 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#define LDC_STATE_INVALID 0x00 478c2ecf20Sopenharmony_ci#define LDC_STATE_INIT 0x01 488c2ecf20Sopenharmony_ci#define LDC_STATE_BOUND 0x02 498c2ecf20Sopenharmony_ci#define LDC_STATE_READY 0x03 508c2ecf20Sopenharmony_ci#define LDC_STATE_CONNECTED 0x04 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#define LDC_PACKET_SIZE 64 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistruct ldc_channel; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci/* Allocate state for a channel. */ 578c2ecf20Sopenharmony_cistruct ldc_channel *ldc_alloc(unsigned long id, 588c2ecf20Sopenharmony_ci const struct ldc_channel_config *cfgp, 598c2ecf20Sopenharmony_ci void *event_arg, 608c2ecf20Sopenharmony_ci const char *name); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci/* Shut down and free state for a channel. */ 638c2ecf20Sopenharmony_civoid ldc_free(struct ldc_channel *lp); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci/* Register TX and RX queues of the link with the hypervisor. */ 668c2ecf20Sopenharmony_ciint ldc_bind(struct ldc_channel *lp); 678c2ecf20Sopenharmony_civoid ldc_unbind(struct ldc_channel *lp); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci/* For non-RAW protocols we need to complete a handshake before 708c2ecf20Sopenharmony_ci * communication can proceed. ldc_connect() does that, if the 718c2ecf20Sopenharmony_ci * handshake completes successfully, an LDC_EVENT_UP event will 728c2ecf20Sopenharmony_ci * be sent up to the driver. 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ciint ldc_connect(struct ldc_channel *lp); 758c2ecf20Sopenharmony_ciint ldc_disconnect(struct ldc_channel *lp); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ciint ldc_state(struct ldc_channel *lp); 788c2ecf20Sopenharmony_civoid ldc_set_state(struct ldc_channel *lp, u8 state); 798c2ecf20Sopenharmony_ciint ldc_mode(struct ldc_channel *lp); 808c2ecf20Sopenharmony_civoid __ldc_print(struct ldc_channel *lp, const char *caller); 818c2ecf20Sopenharmony_ciint ldc_rx_reset(struct ldc_channel *lp); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define ldc_print(chan) __ldc_print(chan, __func__) 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci/* Read and write operations. Only valid when the link is up. */ 868c2ecf20Sopenharmony_ciint ldc_write(struct ldc_channel *lp, const void *buf, 878c2ecf20Sopenharmony_ci unsigned int size); 888c2ecf20Sopenharmony_ciint ldc_read(struct ldc_channel *lp, void *buf, unsigned int size); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci#define LDC_MAP_SHADOW 0x01 918c2ecf20Sopenharmony_ci#define LDC_MAP_DIRECT 0x02 928c2ecf20Sopenharmony_ci#define LDC_MAP_IO 0x04 938c2ecf20Sopenharmony_ci#define LDC_MAP_R 0x08 948c2ecf20Sopenharmony_ci#define LDC_MAP_W 0x10 958c2ecf20Sopenharmony_ci#define LDC_MAP_X 0x20 968c2ecf20Sopenharmony_ci#define LDC_MAP_RW (LDC_MAP_R | LDC_MAP_W) 978c2ecf20Sopenharmony_ci#define LDC_MAP_RWX (LDC_MAP_R | LDC_MAP_W | LDC_MAP_X) 988c2ecf20Sopenharmony_ci#define LDC_MAP_ALL 0x03f 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistruct ldc_trans_cookie { 1018c2ecf20Sopenharmony_ci u64 cookie_addr; 1028c2ecf20Sopenharmony_ci u64 cookie_size; 1038c2ecf20Sopenharmony_ci}; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistruct scatterlist; 1068c2ecf20Sopenharmony_ciint ldc_map_sg(struct ldc_channel *lp, 1078c2ecf20Sopenharmony_ci struct scatterlist *sg, int num_sg, 1088c2ecf20Sopenharmony_ci struct ldc_trans_cookie *cookies, int ncookies, 1098c2ecf20Sopenharmony_ci unsigned int map_perm); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ciint ldc_map_single(struct ldc_channel *lp, 1128c2ecf20Sopenharmony_ci void *buf, unsigned int len, 1138c2ecf20Sopenharmony_ci struct ldc_trans_cookie *cookies, int ncookies, 1148c2ecf20Sopenharmony_ci unsigned int map_perm); 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_civoid ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies, 1178c2ecf20Sopenharmony_ci int ncookies); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ciint ldc_copy(struct ldc_channel *lp, int copy_dir, 1208c2ecf20Sopenharmony_ci void *buf, unsigned int len, unsigned long offset, 1218c2ecf20Sopenharmony_ci struct ldc_trans_cookie *cookies, int ncookies); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistatic inline int ldc_get_dring_entry(struct ldc_channel *lp, 1248c2ecf20Sopenharmony_ci void *buf, unsigned int len, 1258c2ecf20Sopenharmony_ci unsigned long offset, 1268c2ecf20Sopenharmony_ci struct ldc_trans_cookie *cookies, 1278c2ecf20Sopenharmony_ci int ncookies) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci return ldc_copy(lp, LDC_COPY_IN, buf, len, offset, cookies, ncookies); 1308c2ecf20Sopenharmony_ci} 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic inline int ldc_put_dring_entry(struct ldc_channel *lp, 1338c2ecf20Sopenharmony_ci void *buf, unsigned int len, 1348c2ecf20Sopenharmony_ci unsigned long offset, 1358c2ecf20Sopenharmony_ci struct ldc_trans_cookie *cookies, 1368c2ecf20Sopenharmony_ci int ncookies) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci return ldc_copy(lp, LDC_COPY_OUT, buf, len, offset, cookies, ncookies); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_civoid *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len, 1428c2ecf20Sopenharmony_ci struct ldc_trans_cookie *cookies, 1438c2ecf20Sopenharmony_ci int *ncookies, unsigned int map_perm); 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_civoid ldc_free_exp_dring(struct ldc_channel *lp, void *buf, 1468c2ecf20Sopenharmony_ci unsigned int len, 1478c2ecf20Sopenharmony_ci struct ldc_trans_cookie *cookies, int ncookies); 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci#endif /* _SPARC64_LDC_H */ 150