hc
2025-02-14 bbb9540dc49f70f6b703d1c8d1b85fa5f602d86e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _SPARC64_LDC_H
#define _SPARC64_LDC_H
 
#include <asm/hypervisor.h>
 
extern int ldom_domaining_enabled;
void ldom_set_var(const char *var, const char *value);
void ldom_reboot(const char *boot_command);
void ldom_power_off(void);
 
/* The event handler will be evoked when link state changes
 * or data becomes available on the receive side.
 *
 * For non-RAW links, if the LDC_EVENT_RESET event arrives the
 * driver should reset all of it's internal state and reinvoke
 * ldc_connect() to try and bring the link up again.
 *
 * For RAW links, ldc_connect() is not used.  Instead the driver
 * just waits for the LDC_EVENT_UP event.
 */
struct ldc_channel_config {
   void (*event)(void *arg, int event);
 
   u32            mtu;
   unsigned int        rx_irq;
   unsigned int        tx_irq;
   u8            mode;
#define LDC_MODE_RAW        0x00
#define LDC_MODE_UNRELIABLE    0x01
#define LDC_MODE_RESERVED    0x02
#define LDC_MODE_STREAM        0x03
 
   u8            debug;
#define LDC_DEBUG_HS        0x01
#define LDC_DEBUG_STATE        0x02
#define LDC_DEBUG_RX        0x04
#define LDC_DEBUG_TX        0x08
#define LDC_DEBUG_DATA        0x10
};
 
#define LDC_EVENT_RESET        0x01
#define LDC_EVENT_UP        0x02
#define LDC_EVENT_DATA_READY    0x04
 
#define LDC_STATE_INVALID    0x00
#define LDC_STATE_INIT        0x01
#define LDC_STATE_BOUND        0x02
#define LDC_STATE_READY        0x03
#define LDC_STATE_CONNECTED    0x04
 
#define    LDC_PACKET_SIZE        64
 
struct ldc_channel;
 
/* Allocate state for a channel.  */
struct ldc_channel *ldc_alloc(unsigned long id,
                 const struct ldc_channel_config *cfgp,
                 void *event_arg,
                 const char *name);
 
/* Shut down and free state for a channel.  */
void ldc_free(struct ldc_channel *lp);
 
/* Register TX and RX queues of the link with the hypervisor.  */
int ldc_bind(struct ldc_channel *lp);
void ldc_unbind(struct ldc_channel *lp);
 
/* For non-RAW protocols we need to complete a handshake before
 * communication can proceed.  ldc_connect() does that, if the
 * handshake completes successfully, an LDC_EVENT_UP event will
 * be sent up to the driver.
 */
int ldc_connect(struct ldc_channel *lp);
int ldc_disconnect(struct ldc_channel *lp);
 
int ldc_state(struct ldc_channel *lp);
void ldc_set_state(struct ldc_channel *lp, u8 state);
int ldc_mode(struct ldc_channel *lp);
void __ldc_print(struct ldc_channel *lp, const char *caller);
int ldc_rx_reset(struct ldc_channel *lp);
 
#define    ldc_print(chan)    __ldc_print(chan, __func__)
 
/* Read and write operations.  Only valid when the link is up.  */
int ldc_write(struct ldc_channel *lp, const void *buf,
         unsigned int size);
int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size);
 
#define LDC_MAP_SHADOW    0x01
#define LDC_MAP_DIRECT    0x02
#define LDC_MAP_IO    0x04
#define LDC_MAP_R    0x08
#define LDC_MAP_W    0x10
#define LDC_MAP_X    0x20
#define LDC_MAP_RW    (LDC_MAP_R | LDC_MAP_W)
#define LDC_MAP_RWX    (LDC_MAP_R | LDC_MAP_W | LDC_MAP_X)
#define LDC_MAP_ALL    0x03f
 
struct ldc_trans_cookie {
   u64            cookie_addr;
   u64            cookie_size;
};
 
struct scatterlist;
int ldc_map_sg(struct ldc_channel *lp,
          struct scatterlist *sg, int num_sg,
          struct ldc_trans_cookie *cookies, int ncookies,
          unsigned int map_perm);
 
int ldc_map_single(struct ldc_channel *lp,
          void *buf, unsigned int len,
          struct ldc_trans_cookie *cookies, int ncookies,
          unsigned int map_perm);
 
void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies,
          int ncookies);
 
int ldc_copy(struct ldc_channel *lp, int copy_dir,
        void *buf, unsigned int len, unsigned long offset,
        struct ldc_trans_cookie *cookies, int ncookies);
 
static inline int ldc_get_dring_entry(struct ldc_channel *lp,
                     void *buf, unsigned int len,
                     unsigned long offset,
                     struct ldc_trans_cookie *cookies,
                     int ncookies)
{
   return ldc_copy(lp, LDC_COPY_IN, buf, len, offset, cookies, ncookies);
}
 
static inline int ldc_put_dring_entry(struct ldc_channel *lp,
                     void *buf, unsigned int len,
                     unsigned long offset,
                     struct ldc_trans_cookie *cookies,
                     int ncookies)
{
   return ldc_copy(lp, LDC_COPY_OUT, buf, len, offset, cookies, ncookies);
}
 
void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len,
             struct ldc_trans_cookie *cookies,
             int *ncookies, unsigned int map_perm);
 
void ldc_free_exp_dring(struct ldc_channel *lp, void *buf,
               unsigned int len,
               struct ldc_trans_cookie *cookies, int ncookies);
 
#endif /* _SPARC64_LDC_H */