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