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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _SOC_QCOM_GLINK_XPRT_IF_H_
#define _SOC_QCOM_GLINK_XPRT_IF_H_
#include <linux/bitops.h>
#include <linux/list.h>
#include <linux/types.h>
struct glink_core_xprt_ctx;
struct glink_core_if;
struct channel_ctx;
struct glink_core_rx_intent;
enum buf_type {
LINEAR = 0,
VECTOR,
};
enum xprt_ids {
SMEM_XPRT_ID = 100,
SPIV2_XPRT_ID = SMEM_XPRT_ID,
SMD_TRANS_XPRT_ID = 200,
LLOOP_XPRT_ID = 300,
MOCK_XPRT_HIGH_ID = 390,
MOCK_XPRT_ID = 400,
MOCK_XPRT_LOW_ID = 410,
};
#define GCAP_SIGNALS BIT(0)
#define GCAP_INTENTLESS BIT(1)
#define GCAP_TRACER_PKT BIT(2)
#define GCAP_AUTO_QUEUE_RX_INT BIT(3)
/**
* struct glink_core_tx_pkt - Transmit Packet information
* @list_done: Index to the channel's transmit queue.
* @list_done: Index to the channel's acknowledgment queue.
* @pkt_priv: Private information specific to the packet.
* @data: Pointer to the buffer containing the data.
* @riid: Remote receive intent used to transmit the packet.
* @rcid: Remote channel receiving the packet.
* @size: Total size of the data in the packet.
* @tx_len: Data length to transmit in the current transmit slot.
* @size_remaining: Remaining size of the data in the packet.
* @intent_size: Receive intent size queued by the remote side.
* @tracer_pkt: Flag to indicate if the packet is a tracer packet.
* @iovec: Pointer to the vector buffer packet.
* @vprovider: Packet-specific virtual buffer provider function.
* @pprovider: Packet-specific physical buffer provider function.
* @cookie: Transport-specific cookie
* @pkt_ref: Active references to the packet.
*/
struct glink_core_tx_pkt {
struct list_head list_node;
struct list_head list_done;
const void *pkt_priv;
const void *data;
uint32_t riid;
uint32_t rcid;
uint32_t size;
uint32_t tx_len;
uint32_t size_remaining;
size_t intent_size;
bool tracer_pkt;
void *iovec;
void * (*vprovider)(void *iovec, size_t offset, size_t *size);
void * (*pprovider)(void *iovec, size_t offset, size_t *size);
void *cookie;
struct rwref_lock pkt_ref;
};
/**
* Note - each call to register the interface must pass a unique
* instance of this data.
*/
struct glink_transport_if {
/* Negotiation */
void (*tx_cmd_version)(struct glink_transport_if *if_ptr,
uint32_t version,
uint32_t features);
void (*tx_cmd_version_ack)(struct glink_transport_if *if_ptr,
uint32_t version,
uint32_t features);
uint32_t (*set_version)(struct glink_transport_if *if_ptr,
uint32_t version,
uint32_t features);
/* channel state */
int (*tx_cmd_ch_open)(struct glink_transport_if *if_ptr, uint32_t lcid,
const char *name, uint16_t req_xprt);
int (*tx_cmd_ch_close)(struct glink_transport_if *if_ptr,
uint32_t lcid);
void (*tx_cmd_ch_remote_open_ack)(struct glink_transport_if *if_ptr,
uint32_t rcid, uint16_t xprt_resp);
void (*tx_cmd_ch_remote_close_ack)(struct glink_transport_if *if_ptr,
uint32_t rcid);
int (*ssr)(struct glink_transport_if *if_ptr);
void (*subsys_up)(struct glink_transport_if *if_ptr);
/* channel data */
int (*allocate_rx_intent)(struct glink_transport_if *if_ptr,
size_t size,
struct glink_core_rx_intent *intent);
int (*deallocate_rx_intent)(struct glink_transport_if *if_ptr,
struct glink_core_rx_intent *intent);
/* Optional */
int (*reuse_rx_intent)(struct glink_transport_if *if_ptr,
struct glink_core_rx_intent *intent);
int (*tx_cmd_local_rx_intent)(struct glink_transport_if *if_ptr,
uint32_t lcid, size_t size, uint32_t liid);
void (*tx_cmd_local_rx_done)(struct glink_transport_if *if_ptr,
uint32_t lcid, uint32_t liid, bool reuse);
int (*tx)(struct glink_transport_if *if_ptr, uint32_t lcid,
struct glink_core_tx_pkt *pctx);
int (*tx_cmd_rx_intent_req)(struct glink_transport_if *if_ptr,
uint32_t lcid, size_t size);
int (*tx_cmd_remote_rx_intent_req_ack)(
struct glink_transport_if *if_ptr,
uint32_t lcid, bool granted);
int (*tx_cmd_set_sigs)(struct glink_transport_if *if_ptr,
uint32_t lcid, uint32_t sigs);
/* Optional. If NULL at xprt registration, dummies will be used */
int (*poll)(struct glink_transport_if *if_ptr, uint32_t lcid);
int (*mask_rx_irq)(struct glink_transport_if *if_ptr, uint32_t lcid,
bool mask, void *pstruct);
int (*wait_link_down)(struct glink_transport_if *if_ptr);
int (*tx_cmd_tracer_pkt)(struct glink_transport_if *if_ptr,
uint32_t lcid, struct glink_core_tx_pkt *pctx);
unsigned long (*get_power_vote_ramp_time)(
struct glink_transport_if *if_ptr, uint32_t state);
int (*power_vote)(struct glink_transport_if *if_ptr, uint32_t state);
int (*power_unvote)(struct glink_transport_if *if_ptr);
int (*rx_rt_vote)(struct glink_transport_if *if_ptr);
int (*rx_rt_unvote)(struct glink_transport_if *if_ptr);
/*
* Keep data pointers at the end of the structure after all function
* pointer to allow for in-place initialization.
*/
/* private pointer for core */
struct glink_core_xprt_ctx *glink_core_priv;
/* core pointer (set during transport registration) */
struct glink_core_if *glink_core_if_ptr;
};
#ifdef CONFIG_MSM_GLINK
/**
* get_tx_vaddr() - Get the virtual address from which the tx has to be done
* @pctx: transmit packet context.
* @offset: offset into the packet.
* @tx_size: pointer to hold the length of the contiguous buffer
* space.
*
* Return: Address from which the tx has to be done.
*/
static inline void *get_tx_vaddr(struct glink_core_tx_pkt *pctx, size_t offset,
size_t *tx_size)
{
void *pdata;
if (pctx->vprovider) {
return pctx->vprovider((void *)pctx->iovec, offset, tx_size);
} else if (pctx->pprovider) {
pdata = pctx->pprovider((void *)pctx->iovec, offset, tx_size);
return phys_to_virt((unsigned long)pdata);
}
return NULL;
}
/**
* glink_xprt_name_to_id() - convert transport name to id
* @name: Name of the transport.
* @id: Assigned id.
*
* Return: 0 on success or standard Linux error code.
*/
int glink_xprt_name_to_id(const char *name, uint16_t *id);
#else /* CONFIG_MSM_GLINK */
static inline void *get_tx_vaddr(struct glink_core_tx_pkt *pctx, size_t offset,
size_t *tx_size)
{
return NULL;
}
static inline int glink_xprt_name_to_id(const char *name, uint16_t *id)
{
return -ENODEV;
}
#endif /* CONFIG_MSM_GLINK */
#endif /* _SOC_QCOM_GLINK_XPRT_IF_H_ */
|