/* SPDX-License-Identifier: GPL-2.0+ */
/*
* SSH packet transport layer .
*
* Copyright ( C ) 2019 - 2022 Maximilian Luz < luzmaximilian @ gmail . com >
*/
#ifndef _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
#define _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
#include <linux/atomic.h>
#include <linux/kfifo.h>
#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/serdev.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <linux/surface_aggregator/serial_hub.h>
#include "ssh_parser.h"
/**
* enum ssh_ptl_state_flags - State - flags for & struct ssh_ptl .
*
* @ SSH_PTL_SF_SHUTDOWN_BIT :
* Indicates that the packet transport layer has been shut down or is
* being shut down and should not accept any new packets / data .
*/
enum ssh_ptl_state_flags {
SSH_PTL_SF_SHUTDOWN_BIT,
};
/**
* struct ssh_ptl_ops - Callback operations for packet transport layer .
* @ data_received : Function called when a data - packet has been received . Both ,
* the packet layer on which the packet has been received and
* the packet ' s payload data are provided to this function .
*/
struct ssh_ptl_ops {
void (*data_received)(struct ssh_ptl *p, const struct ssam_span *data);
};
/**
* struct ssh_ptl - SSH packet transport layer .
* @ serdev : Serial device providing the underlying data transport .
* @ state : State ( - flags ) of the transport layer .
* @ queue : Packet submission queue .
* @ queue . lock : Lock for modifying the packet submission queue .
* @ queue . head : List - head of the packet submission queue .
* @ pending : Set / list of pending packets .
* @ pending . lock : Lock for modifying the pending set .
* @ pending . head : List - head of the pending set / list .
* @ pending . count : Number of currently pending packets .
* @ tx : Transmitter subsystem .
* @ tx . running : Flag indicating ( desired ) transmitter thread state .
* @ tx . thread : Transmitter thread .
* @ tx . thread_cplt_tx : Completion for transmitter thread waiting on transfer .
* @ tx . thread_cplt_pkt : Completion for transmitter thread waiting on packets .
* @ tx . packet_wq : Waitqueue - head for packet transmit completion .
* @ rx : Receiver subsystem .
* @ rx . thread : Receiver thread .
* @ rx . wq : Waitqueue - head for receiver thread .
* @ rx . fifo : Buffer for receiving data / pushing data to receiver thread .
* @ rx . buf : Buffer for evaluating data on receiver thread .
* @ rx . blocked : List of recent / blocked sequence IDs to detect retransmission .
* @ rx . blocked . seqs : Array of blocked sequence IDs .
* @ rx . blocked . offset : Offset indicating where a new ID should be inserted .
* @ rtx_timeout : Retransmission timeout subsystem .
* @ rtx_timeout . lock : Lock for modifying the retransmission timeout reaper .
* @ rtx_timeout . timeout : Timeout interval for retransmission .
* @ rtx_timeout . expires : Time specifying when the reaper work is next scheduled .
* @ rtx_timeout . reaper : Work performing timeout checks and subsequent actions .
* @ ops : Packet layer operations .
*/
struct ssh_ptl {
struct serdev_device *serdev;
unsigned long state;
struct {
spinlock_t lock;
struct list_head head;
} queue;
struct {
spinlock_t lock;
struct list_head head;
atomic_t count;
} pending;
struct {
atomic_t running;
struct task_struct *thread;
struct completion thread_cplt_tx;
struct completion thread_cplt_pkt;
struct wait_queue_head packet_wq;
} tx;
struct {
struct task_struct *thread;
struct wait_queue_head wq;
struct kfifo fifo;
struct sshp_buf buf;
struct {
u16 seqs[8 ];
u16 offset;
} blocked;
} rx;
struct {
spinlock_t lock;
ktime_t timeout;
ktime_t expires;
struct delayed_work reaper;
} rtx_timeout;
struct ssh_ptl_ops ops;
};
#define __ssam_prcond(func, p, fmt, ...) \
do { \
typeof(p) __p = (p); \
\
if (__p) \
func(__p, fmt, ## __VA_ARGS__); \
} while (0 )
#define ptl_dbg(p, fmt, ...) dev_dbg(&(p)->serdev->dev, fmt, ## __VA_ARGS__)
#define ptl_info(p, fmt, ...) dev_info(&(p)->serdev->dev, fmt, ## __VA_ARGS__)
#define ptl_warn(p, fmt, ...) dev_warn(&(p)->serdev->dev, fmt, ## __VA_ARGS__)
#define ptl_err(p, fmt, ...) dev_err(&(p)->serdev->dev, fmt, ## __VA_ARGS__)
#define ptl_dbg_cond(p, fmt, ...) __ssam_prcond(ptl_dbg, p, fmt, ## __VA_ARGS__)
#define to_ssh_ptl(ptr, member) \
container_of(ptr, struct ssh_ptl, member)
int ssh_ptl_init(struct ssh_ptl *ptl, struct serdev_device *serdev,
struct ssh_ptl_ops *ops);
void ssh_ptl_destroy(struct ssh_ptl *ptl);
/**
* ssh_ptl_get_device ( ) - Get device associated with packet transport layer .
* @ ptl : The packet transport layer .
*
* Return : Returns the device on which the given packet transport layer builds
* upon .
*/
static inline struct device *ssh_ptl_get_device(struct ssh_ptl *ptl)
{
return ptl->serdev ? &ptl->serdev->dev : NULL;
}
int ssh_ptl_tx_start(struct ssh_ptl *ptl);
int ssh_ptl_tx_stop(struct ssh_ptl *ptl);
int ssh_ptl_rx_start(struct ssh_ptl *ptl);
int ssh_ptl_rx_stop(struct ssh_ptl *ptl);
void ssh_ptl_shutdown(struct ssh_ptl *ptl);
int ssh_ptl_submit(struct ssh_ptl *ptl, struct ssh_packet *p);
void ssh_ptl_cancel(struct ssh_packet *p);
ssize_t ssh_ptl_rx_rcvbuf(struct ssh_ptl *ptl, const u8 *buf, size_t n);
/**
* ssh_ptl_tx_wakeup_transfer ( ) - Wake up packet transmitter thread for
* transfer .
* @ ptl : The packet transport layer .
*
* Wakes up the packet transmitter thread , notifying it that the underlying
* transport has more space for data to be transmitted . If the packet
* transport layer has been shut down , calls to this function will be ignored .
*/
static inline void ssh_ptl_tx_wakeup_transfer(struct ssh_ptl *ptl)
{
if (test_bit(SSH_PTL_SF_SHUTDOWN_BIT, &ptl->state))
return ;
complete(&ptl->tx.thread_cplt_tx);
}
void ssh_packet_init(struct ssh_packet *packet, unsigned long type,
u8 priority, const struct ssh_packet_ops *ops);
int ssh_ctrl_packet_cache_init(void );
void ssh_ctrl_packet_cache_destroy(void );
#endif /* _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H */
Messung V0.5 in Prozent C=96 H=95 G=95
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-10-04)
¤
*© Formatika GbR, Deutschland