1 /* SPDX-License-Identifier: GPL-2.0+ */
3 * SSH packet transport layer.
5 * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com>
8 #ifndef _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
9 #define _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
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>
21 #include <linux/surface_aggregator/serial_hub.h>
22 #include "ssh_parser.h"
25 * enum ssh_ptl_state_flags - State-flags for &struct ssh_ptl.
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.
31 enum ssh_ptl_state_flags
{
32 SSH_PTL_SF_SHUTDOWN_BIT
,
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.
42 void (*data_received
)(struct ssh_ptl
*p
, const struct ssam_span
*data
);
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.
78 struct serdev_device
*serdev
;
83 struct list_head head
;
88 struct list_head head
;
94 struct task_struct
*thread
;
95 struct completion thread_cplt_tx
;
96 struct completion thread_cplt_pkt
;
97 struct wait_queue_head packet_wq
;
101 struct task_struct
*thread
;
102 struct wait_queue_head wq
;
116 struct delayed_work reaper
;
119 struct ssh_ptl_ops ops
;
122 #define __ssam_prcond(func, p, fmt, ...) \
124 typeof(p) __p = (p); \
127 func(__p, fmt, ##__VA_ARGS__); \
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__)
136 #define to_ssh_ptl(ptr, member) \
137 container_of(ptr, struct ssh_ptl, member)
139 int ssh_ptl_init(struct ssh_ptl
*ptl
, struct serdev_device
*serdev
,
140 struct ssh_ptl_ops
*ops
);
142 void ssh_ptl_destroy(struct ssh_ptl
*ptl
);
145 * ssh_ptl_get_device() - Get device associated with packet transport layer.
146 * @ptl: The packet transport layer.
148 * Return: Returns the device on which the given packet transport layer builds
151 static inline struct device
*ssh_ptl_get_device(struct ssh_ptl
*ptl
)
153 return ptl
->serdev
? &ptl
->serdev
->dev
: NULL
;
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
);
162 int ssh_ptl_submit(struct ssh_ptl
*ptl
, struct ssh_packet
*p
);
163 void ssh_ptl_cancel(struct ssh_packet
*p
);
165 ssize_t
ssh_ptl_rx_rcvbuf(struct ssh_ptl
*ptl
, const u8
*buf
, size_t n
);
168 * ssh_ptl_tx_wakeup_transfer() - Wake up packet transmitter thread for
170 * @ptl: The packet transport layer.
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.
176 static inline void ssh_ptl_tx_wakeup_transfer(struct ssh_ptl
*ptl
)
178 if (test_bit(SSH_PTL_SF_SHUTDOWN_BIT
, &ptl
->state
))
181 complete(&ptl
->tx
.thread_cplt_tx
);
184 void ssh_packet_init(struct ssh_packet
*packet
, unsigned long type
,
185 u8 priority
, const struct ssh_packet_ops
*ops
);
187 int ssh_ctrl_packet_cache_init(void);
188 void ssh_ctrl_packet_cache_destroy(void);
190 #endif /* _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H */