1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * ISHTP client logic |
4 | * |
5 | * Copyright (c) 2003-2016, Intel Corporation. |
6 | */ |
7 | |
8 | #ifndef _ISHTP_CLIENT_H_ |
9 | #define _ISHTP_CLIENT_H_ |
10 | |
11 | #include <linux/types.h> |
12 | #include "ishtp-dev.h" |
13 | |
14 | /* Tx and Rx ring size */ |
15 | #define CL_DEF_RX_RING_SIZE 2 |
16 | #define CL_DEF_TX_RING_SIZE 2 |
17 | #define CL_MAX_RX_RING_SIZE 32 |
18 | #define CL_MAX_TX_RING_SIZE 32 |
19 | |
20 | #define DMA_SLOT_SIZE 4096 |
21 | /* Number of IPC fragments after which it's worth sending via DMA */ |
22 | #define DMA_WORTH_THRESHOLD 3 |
23 | |
24 | /* DMA/IPC Tx paths. Other the default means enforcement */ |
25 | #define CL_TX_PATH_DEFAULT 0 |
26 | #define CL_TX_PATH_IPC 1 |
27 | #define CL_TX_PATH_DMA 2 |
28 | |
29 | /* Client Tx buffer list entry */ |
30 | struct ishtp_cl_tx_ring { |
31 | struct list_head list; |
32 | struct ishtp_msg_data send_buf; |
33 | }; |
34 | |
35 | /* ISHTP client instance */ |
36 | struct ishtp_cl { |
37 | struct list_head link; |
38 | struct ishtp_device *dev; |
39 | enum cl_state state; |
40 | int status; |
41 | |
42 | /* Link to ISHTP bus device */ |
43 | struct ishtp_cl_device *device; |
44 | |
45 | /* ID of client connected */ |
46 | uint8_t host_client_id; |
47 | uint8_t fw_client_id; |
48 | uint8_t ishtp_flow_ctrl_creds; |
49 | uint8_t out_flow_ctrl_creds; |
50 | |
51 | /* dma */ |
52 | int last_tx_path; |
53 | /* 0: ack wasn't received,1:ack was received */ |
54 | int last_dma_acked; |
55 | unsigned char *last_dma_addr; |
56 | /* 0: ack wasn't received,1:ack was received */ |
57 | int last_ipc_acked; |
58 | |
59 | /* Rx ring buffer pool */ |
60 | unsigned int rx_ring_size; |
61 | struct ishtp_cl_rb free_rb_list; |
62 | spinlock_t free_list_spinlock; |
63 | /* Rx in-process list */ |
64 | struct ishtp_cl_rb in_process_list; |
65 | spinlock_t in_process_spinlock; |
66 | |
67 | /* Client Tx buffers list */ |
68 | unsigned int tx_ring_size; |
69 | struct ishtp_cl_tx_ring tx_list, tx_free_list; |
70 | int tx_ring_free_size; |
71 | spinlock_t tx_list_spinlock; |
72 | spinlock_t tx_free_list_spinlock; |
73 | size_t tx_offs; /* Offset in buffer at head of 'tx_list' */ |
74 | |
75 | /** |
76 | * if we get a FC, and the list is not empty, we must know whether we |
77 | * are at the middle of sending. |
78 | * if so -need to increase FC counter, otherwise, need to start sending |
79 | * the first msg in list |
80 | * (!)This is for counting-FC implementation only. Within single-FC the |
81 | * other party may NOT send FC until it receives complete message |
82 | */ |
83 | int sending; |
84 | |
85 | /* Send FC spinlock */ |
86 | spinlock_t fc_spinlock; |
87 | |
88 | /* wait queue for connect and disconnect response from FW */ |
89 | wait_queue_head_t wait_ctrl_res; |
90 | |
91 | /* Error stats */ |
92 | unsigned int err_send_msg; |
93 | unsigned int err_send_fc; |
94 | |
95 | /* Send/recv stats */ |
96 | unsigned int send_msg_cnt_ipc; |
97 | unsigned int send_msg_cnt_dma; |
98 | unsigned int recv_msg_cnt_ipc; |
99 | unsigned int recv_msg_cnt_dma; |
100 | unsigned int recv_msg_num_frags; |
101 | unsigned int ishtp_flow_ctrl_cnt; |
102 | unsigned int out_flow_ctrl_cnt; |
103 | |
104 | /* Rx msg ... out FC timing */ |
105 | ktime_t ts_rx; |
106 | ktime_t ts_out_fc; |
107 | ktime_t ts_max_fc_delay; |
108 | void *client_data; |
109 | }; |
110 | |
111 | /* Client connection managenment internal functions */ |
112 | int ishtp_can_client_connect(struct ishtp_device *ishtp_dev, guid_t *uuid); |
113 | int ishtp_fw_cl_by_id(struct ishtp_device *dev, uint8_t client_id); |
114 | void ishtp_cl_send_msg(struct ishtp_device *dev, struct ishtp_cl *cl); |
115 | void recv_ishtp_cl_msg(struct ishtp_device *dev, |
116 | struct ishtp_msg_hdr *ishtp_hdr); |
117 | int ishtp_cl_read_start(struct ishtp_cl *cl); |
118 | |
119 | /* Ring Buffer I/F */ |
120 | int ishtp_cl_alloc_rx_ring(struct ishtp_cl *cl); |
121 | int ishtp_cl_alloc_tx_ring(struct ishtp_cl *cl); |
122 | void ishtp_cl_free_rx_ring(struct ishtp_cl *cl); |
123 | void ishtp_cl_free_tx_ring(struct ishtp_cl *cl); |
124 | int ishtp_cl_get_tx_free_buffer_size(struct ishtp_cl *cl); |
125 | int ishtp_cl_get_tx_free_rings(struct ishtp_cl *cl); |
126 | |
127 | /* DMA I/F functions */ |
128 | void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, |
129 | struct dma_xfer_hbm *hbm); |
130 | void ishtp_cl_alloc_dma_buf(struct ishtp_device *dev); |
131 | void ishtp_cl_free_dma_buf(struct ishtp_device *dev); |
132 | void *ishtp_cl_get_dma_send_buf(struct ishtp_device *dev, |
133 | uint32_t size); |
134 | void ishtp_cl_release_dma_acked_mem(struct ishtp_device *dev, |
135 | void *msg_addr, |
136 | uint8_t size); |
137 | |
138 | /* Request blocks alloc/free I/F */ |
139 | struct ishtp_cl_rb *ishtp_io_rb_init(struct ishtp_cl *cl); |
140 | void ishtp_io_rb_free(struct ishtp_cl_rb *priv_rb); |
141 | int ishtp_io_rb_alloc_buf(struct ishtp_cl_rb *rb, size_t length); |
142 | |
143 | /** |
144 | * ishtp_cl_cmp_id - tells if file private data have same id |
145 | * returns true - if ids are the same and not NULL |
146 | */ |
147 | static inline bool ishtp_cl_cmp_id(const struct ishtp_cl *cl1, |
148 | const struct ishtp_cl *cl2) |
149 | { |
150 | return cl1 && cl2 && |
151 | (cl1->host_client_id == cl2->host_client_id) && |
152 | (cl1->fw_client_id == cl2->fw_client_id); |
153 | } |
154 | |
155 | #endif /* _ISHTP_CLIENT_H_ */ |
156 | |