linux/drivers/platform/surface/aggregator/ssh_packet_layer.h
<<
>>
Prefs
   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 */
  31enum 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 */
  41struct 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 */
  77struct 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
 139int ssh_ptl_init(struct ssh_ptl *ptl, struct serdev_device *serdev,
 140                 struct ssh_ptl_ops *ops);
 141
 142void 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 */
 151static inline struct device *ssh_ptl_get_device(struct ssh_ptl *ptl)
 152{
 153        return ptl->serdev ? &ptl->serdev->dev : NULL;
 154}
 155
 156int ssh_ptl_tx_start(struct ssh_ptl *ptl);
 157int ssh_ptl_tx_stop(struct ssh_ptl *ptl);
 158int ssh_ptl_rx_start(struct ssh_ptl *ptl);
 159int ssh_ptl_rx_stop(struct ssh_ptl *ptl);
 160void ssh_ptl_shutdown(struct ssh_ptl *ptl);
 161
 162int ssh_ptl_submit(struct ssh_ptl *ptl, struct ssh_packet *p);
 163void ssh_ptl_cancel(struct ssh_packet *p);
 164
 165int 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 */
 176static 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
 184void ssh_packet_init(struct ssh_packet *packet, unsigned long type,
 185                     u8 priority, const struct ssh_packet_ops *ops);
 186
 187int ssh_ctrl_packet_cache_init(void);
 188void ssh_ctrl_packet_cache_destroy(void);
 189
 190#endif /* _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H */
 191