platform/surface: aggregator: Update copyright
[linux-2.6-microblaze.git] / drivers / platform / surface / aggregator / ssh_packet_layer.h
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * SSH packet transport layer.
4  *
5  * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
6  */
7
8 #ifndef _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
9 #define _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
10
11 #include <linux/atomic.h>
12 #include <linux/kfifo.h>
13 #include <linux/ktime.h>
14 #include <linux/list.h>
15 #include <linux/serdev.h>
16 #include <linux/spinlock.h>
17 #include <linux/types.h>
18 #include <linux/wait.h>
19 #include <linux/workqueue.h>
20
21 #include <linux/surface_aggregator/serial_hub.h>
22 #include "ssh_parser.h"
23
24 /**
25  * enum ssh_ptl_state_flags - State-flags for &struct ssh_ptl.
26  *
27  * @SSH_PTL_SF_SHUTDOWN_BIT:
28  *      Indicates that the packet transport layer has been shut down or is
29  *      being shut down and should not accept any new packets/data.
30  */
31 enum ssh_ptl_state_flags {
32         SSH_PTL_SF_SHUTDOWN_BIT,
33 };
34
35 /**
36  * struct ssh_ptl_ops - Callback operations for packet transport layer.
37  * @data_received: Function called when a data-packet has been received. Both,
38  *                 the packet layer on which the packet has been received and
39  *                 the packet's payload data are provided to this function.
40  */
41 struct ssh_ptl_ops {
42         void (*data_received)(struct ssh_ptl *p, const struct ssam_span *data);
43 };
44
45 /**
46  * struct ssh_ptl - SSH packet transport layer.
47  * @serdev:        Serial device providing the underlying data transport.
48  * @state:         State(-flags) of the transport layer.
49  * @queue:         Packet submission queue.
50  * @queue.lock:    Lock for modifying the packet submission queue.
51  * @queue.head:    List-head of the packet submission queue.
52  * @pending:       Set/list of pending packets.
53  * @pending.lock:  Lock for modifying the pending set.
54  * @pending.head:  List-head of the pending set/list.
55  * @pending.count: Number of currently pending packets.
56  * @tx:            Transmitter subsystem.
57  * @tx.running:    Flag indicating (desired) transmitter thread state.
58  * @tx.thread:     Transmitter thread.
59  * @tx.thread_cplt_tx:  Completion for transmitter thread waiting on transfer.
60  * @tx.thread_cplt_pkt: Completion for transmitter thread waiting on packets.
61  * @tx.packet_wq:  Waitqueue-head for packet transmit completion.
62  * @rx:            Receiver subsystem.
63  * @rx.thread:     Receiver thread.
64  * @rx.wq:         Waitqueue-head for receiver thread.
65  * @rx.fifo:       Buffer for receiving data/pushing data to receiver thread.
66  * @rx.buf:        Buffer for evaluating data on receiver thread.
67  * @rx.blocked:    List of recent/blocked sequence IDs to detect retransmission.
68  * @rx.blocked.seqs:   Array of blocked sequence IDs.
69  * @rx.blocked.offset: Offset indicating where a new ID should be inserted.
70  * @rtx_timeout:   Retransmission timeout subsystem.
71  * @rtx_timeout.lock:    Lock for modifying the retransmission timeout reaper.
72  * @rtx_timeout.timeout: Timeout interval for retransmission.
73  * @rtx_timeout.expires: Time specifying when the reaper work is next scheduled.
74  * @rtx_timeout.reaper:  Work performing timeout checks and subsequent actions.
75  * @ops:           Packet layer operations.
76  */
77 struct ssh_ptl {
78         struct serdev_device *serdev;
79         unsigned long state;
80
81         struct {
82                 spinlock_t lock;
83                 struct list_head head;
84         } queue;
85
86         struct {
87                 spinlock_t lock;
88                 struct list_head head;
89                 atomic_t count;
90         } pending;
91
92         struct {
93                 atomic_t running;
94                 struct task_struct *thread;
95                 struct completion thread_cplt_tx;
96                 struct completion thread_cplt_pkt;
97                 struct wait_queue_head packet_wq;
98         } tx;
99
100         struct {
101                 struct task_struct *thread;
102                 struct wait_queue_head wq;
103                 struct kfifo fifo;
104                 struct sshp_buf buf;
105
106                 struct {
107                         u16 seqs[8];
108                         u16 offset;
109                 } blocked;
110         } rx;
111
112         struct {
113                 spinlock_t lock;
114                 ktime_t timeout;
115                 ktime_t expires;
116                 struct delayed_work reaper;
117         } rtx_timeout;
118
119         struct ssh_ptl_ops ops;
120 };
121
122 #define __ssam_prcond(func, p, fmt, ...)                \
123         do {                                            \
124                 typeof(p) __p = (p);                    \
125                                                         \
126                 if (__p)                                \
127                         func(__p, fmt, ##__VA_ARGS__);  \
128         } while (0)
129
130 #define ptl_dbg(p, fmt, ...)  dev_dbg(&(p)->serdev->dev, fmt, ##__VA_ARGS__)
131 #define ptl_info(p, fmt, ...) dev_info(&(p)->serdev->dev, fmt, ##__VA_ARGS__)
132 #define ptl_warn(p, fmt, ...) dev_warn(&(p)->serdev->dev, fmt, ##__VA_ARGS__)
133 #define ptl_err(p, fmt, ...)  dev_err(&(p)->serdev->dev, fmt, ##__VA_ARGS__)
134 #define ptl_dbg_cond(p, fmt, ...) __ssam_prcond(ptl_dbg, p, fmt, ##__VA_ARGS__)
135
136 #define to_ssh_ptl(ptr, member) \
137         container_of(ptr, struct ssh_ptl, member)
138
139 int ssh_ptl_init(struct ssh_ptl *ptl, struct serdev_device *serdev,
140                  struct ssh_ptl_ops *ops);
141
142 void ssh_ptl_destroy(struct ssh_ptl *ptl);
143
144 /**
145  * ssh_ptl_get_device() - Get device associated with packet transport layer.
146  * @ptl: The packet transport layer.
147  *
148  * Return: Returns the device on which the given packet transport layer builds
149  * upon.
150  */
151 static inline struct device *ssh_ptl_get_device(struct ssh_ptl *ptl)
152 {
153         return ptl->serdev ? &ptl->serdev->dev : NULL;
154 }
155
156 int ssh_ptl_tx_start(struct ssh_ptl *ptl);
157 int ssh_ptl_tx_stop(struct ssh_ptl *ptl);
158 int ssh_ptl_rx_start(struct ssh_ptl *ptl);
159 int ssh_ptl_rx_stop(struct ssh_ptl *ptl);
160 void ssh_ptl_shutdown(struct ssh_ptl *ptl);
161
162 int ssh_ptl_submit(struct ssh_ptl *ptl, struct ssh_packet *p);
163 void ssh_ptl_cancel(struct ssh_packet *p);
164
165 int ssh_ptl_rx_rcvbuf(struct ssh_ptl *ptl, const u8 *buf, size_t n);
166
167 /**
168  * ssh_ptl_tx_wakeup_transfer() - Wake up packet transmitter thread for
169  * transfer.
170  * @ptl: The packet transport layer.
171  *
172  * Wakes up the packet transmitter thread, notifying it that the underlying
173  * transport has more space for data to be transmitted. If the packet
174  * transport layer has been shut down, calls to this function will be ignored.
175  */
176 static inline void ssh_ptl_tx_wakeup_transfer(struct ssh_ptl *ptl)
177 {
178         if (test_bit(SSH_PTL_SF_SHUTDOWN_BIT, &ptl->state))
179                 return;
180
181         complete(&ptl->tx.thread_cplt_tx);
182 }
183
184 void ssh_packet_init(struct ssh_packet *packet, unsigned long type,
185                      u8 priority, const struct ssh_packet_ops *ops);
186
187 int ssh_ctrl_packet_cache_init(void);
188 void ssh_ctrl_packet_cache_destroy(void);
189
190 #endif /* _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H */