blob: d2d089b668c038111b3f611d53ee28e7b378d746 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/**
2 * rwnx_ipc_utils.h
3 *
4 * IPC utility function declarations
5 *
6 * Copyright (C) RivieraWaves 2012-2021
7 */
8#ifndef _RWNX_IPC_UTILS_H_
9#define _RWNX_IPC_UTILS_H_
10
11#include <linux/dma-mapping.h>
12#include <linux/dmapool.h>
13#include <linux/skbuff.h>
14#include "aicwf_debug.h"
15#include "lmac_msg.h"
16#if 0
17#ifdef CONFIG_RWNX_DBG
18/* #define RWNX_DBG(format, arg...) pr_warn(format, ## arg) */
19#define RWNX_DBG printk
20#else
21#define RWNX_DBG(a...) do {} while (0)
22#endif
23
24#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__
25#endif
26
27#ifdef ANDROID_PLATFORM
28#define HIGH_KERNEL_VERSION KERNEL_VERSION(5, 15, 41)
29#else
30#define HIGH_KERNEL_VERSION KERNEL_VERSION(6, 0, 0)
31#endif
32
33enum rwnx_dev_flag {
34 RWNX_DEV_RESTARTING,
35 RWNX_DEV_STACK_RESTARTING,
36 RWNX_DEV_STARTED,
37 RWNX_DEV_ADDING_STA,
38};
39
40struct rwnx_hw;
41struct rwnx_sta;
42struct rwnx_sw_txhdr;
43
44/**
45 * struct rwnx_ipc_buf - Generic IPC buffer
46 * An IPC buffer is a buffer allocated in host memory and "DMA mapped" to be
47 * accessible by the firmware.
48 *
49 * @addr: Host address of the buffer. If NULL other field are invalid
50 * @dma_addr: DMA address of the buffer.
51 * @size: Size, in bytes, of the buffer
52 */
53struct rwnx_ipc_buf
54{
55 void *addr;
56 dma_addr_t dma_addr;
57 size_t size;
58};
59
60/**
61 * struct rwnx_ipc_buf_pool - Generic pool of IPC buffers
62 *
63 * @nb: Number of buffers currently allocated in the pool
64 * @buffers: Array of buffers (size of array is @nb)
65 * @pool: DMA pool in which buffers have been allocated
66 */
67struct rwnx_ipc_buf_pool {
68 int nb;
69 struct rwnx_ipc_buf *buffers;
70 struct dma_pool *pool;
71};
72
73/**
74 * struct rwnx_ipc_dbgdump - IPC buffer for debug dump
75 *
76 * @mutex: Mutex to protect access to debug dump
77 * @buf: IPC buffer
78 */
79struct rwnx_ipc_dbgdump {
80 struct mutex mutex;
81 struct rwnx_ipc_buf buf;
82};
83
84static const u32 rwnx_tx_pattern = 0xCAFEFADE;
85
86/*
87 * Maximum Length of Radiotap header vendor specific data(in bytes)
88 */
89#define RADIOTAP_HDR_VEND_MAX_LEN 16
90
91/*
92 * Maximum Radiotap Header Length without vendor specific data (in bytes)
93 */
94#define RADIOTAP_HDR_MAX_LEN 80
95
96/*
97 * Unsupported HT Frame data length (in bytes)
98 */
99#define UNSUP_RX_VEC_DATA_LEN 2
100
101
102/**
103 * IPC environment control
104 */
105int rwnx_ipc_init(struct rwnx_hw *rwnx_hw, u8 *shared_ram);
106void rwnx_ipc_deinit(struct rwnx_hw *rwnx_hw);
107void rwnx_ipc_start(struct rwnx_hw *rwnx_hw);
108void rwnx_ipc_stop(struct rwnx_hw *rwnx_hw);
109void rwnx_ipc_msg_push(struct rwnx_hw *rwnx_hw, void *msg_buf, uint16_t len);
110
111/**
112 * IPC buffer management
113 */
114int rwnx_ipc_buf_alloc(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf,
115 size_t buf_size, enum dma_data_direction dir, const void *init);
116/**
117 * rwnx_ipc_buf_e2a_alloc() - Allocate an Embedded To Application Input IPC buffer
118 *
119 * @rwnx_hw: Main driver data
120 * @buf: IPC buffer structure to store I{PC buffer information
121 * @buf_size: Size of the Buffer to allocate
122 * @return: 0 on success and != 0 otherwise
123 */
124static inline int rwnx_ipc_buf_e2a_alloc(struct rwnx_hw *rwnx_hw,
125 struct rwnx_ipc_buf *buf,
126 size_t buf_size)
127{
128 return rwnx_ipc_buf_alloc(rwnx_hw, buf, buf_size, DMA_FROM_DEVICE, NULL);
129}
130
131/**
132 * rwnx_ipc_buf_a2e_alloc() - Allocate an Application to Embedded Output IPC buffer
133 *
134 * @rwnx_hw: Main driver data
135 * @buf: IPC buffer structure to store I{PC buffer information
136 * @buf_size: Size of the Buffer to allocate
137 * @buf_data: Initialization data for the buffer. Must be at least
138 * @buf_size long
139 * @return: 0 on success and != 0 otherwise
140 */
141static inline int rwnx_ipc_buf_a2e_alloc(struct rwnx_hw *rwnx_hw,
142 struct rwnx_ipc_buf *buf,
143 size_t buf_size, const void *buf_data)
144{
145 return rwnx_ipc_buf_alloc(rwnx_hw, buf, buf_size, DMA_TO_DEVICE, buf_data);
146}
147void rwnx_ipc_buf_dealloc(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf);
148int rwnx_ipc_buf_a2e_init(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf,
149 void *data, size_t buf_size);
150
151void rwnx_ipc_buf_release(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf,
152 enum dma_data_direction dir);
153
154/**
155 * rwnx_ipc_buf_e2a_release() - Release DMA mapping for an Application to Embedded IPC buffer
156 *
157 * @rwnx_hw: Main driver structure
158 * @buf: IPC buffer to release
159 *
160 * An A2E buffer is realeased when it has been read by the embbeded side. This is
161 * used before giving back a buffer to upper layer, or before deleting a buffer
162 * when rwnx_ipc_buf_dealloc() cannot be used.
163 */
164static inline void rwnx_ipc_buf_a2e_release(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf)
165{
166 rwnx_ipc_buf_release(rwnx_hw, buf, DMA_TO_DEVICE);
167}
168
169/**
170 * rwnx_ipc_buf_e2a_release() - Release DMA mapping for an Embedded to Application IPC buffer
171 *
172 * @rwnx_hw: Main driver structure
173 * @buf: IPC buffer to release
174 *
175 * An E2A buffer is released when it has been updated by the embedded and it's ready
176 * to be forwarded to upper layer (i.e. out of the driver) or to be deleted and
177 * rwnx_ipc_buf_dealloc() cannot be used.
178 *
179 * Note: This function has the side effect to synchronize the buffer for the host so no need to
180 * call rwnx_ipc_buf_e2a_sync().
181 */
182static inline void rwnx_ipc_buf_e2a_release(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf)
183{
184 rwnx_ipc_buf_release(rwnx_hw, buf, DMA_FROM_DEVICE);
185}
186
187void rwnx_ipc_buf_e2a_sync(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf, size_t len);
188void rwnx_ipc_buf_e2a_sync_back(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf, size_t len);
189
190/**
191 * IPC rx buffer management
192 */
193int rwnx_ipc_rxbuf_init(struct rwnx_hw *rwnx_hw, uint32_t rx_bufsz);
194int rwnx_ipc_rxbuf_alloc(struct rwnx_hw *rwnx_hw);
195void rwnx_ipc_rxbuf_dealloc(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf);
196void rwnx_ipc_rxbuf_repush(struct rwnx_hw *rwnx_hw,
197 struct rwnx_ipc_buf *buf);
198#ifdef CONFIG_RWNX_FULLMAC
199void rwnx_ipc_rxdesc_repush(struct rwnx_hw *rwnx_hw,
200 struct rwnx_ipc_buf *buf);
201struct rwnx_ipc_buf *rwnx_ipc_rxbuf_from_hostid(struct rwnx_hw *rwnx_hw, u32 hostid);
202#endif /* CONFIG_RWNX_FULLMAC */
203
204int rwnx_ipc_unsuprxvec_alloc(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf);
205void rwnx_ipc_unsuprxvec_repush(struct rwnx_hw *rwnx_hw, struct rwnx_ipc_buf *buf);
206
207/**
208 * IPC TX specific functions
209 */
210#if 0
211void rwnx_ipc_txdesc_push(struct rwnx_hw *rwnx_hw, struct rwnx_sw_txhdr *sw_txhdr,
212 struct sk_buff *hostid, int hw_queue);
213#endif
214struct sk_buff *rwnx_ipc_get_skb_from_cfm(struct rwnx_hw *rwnx_hw,
215 struct rwnx_ipc_buf *buf);
216void rwnx_ipc_sta_buffer_init(struct rwnx_hw *rwnx_hw, int sta_idx);
217void rwnx_ipc_sta_buffer(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, int tid, int size);
218void rwnx_ipc_tx_drain(struct rwnx_hw *rwnx_hw);
219bool rwnx_ipc_tx_pending(struct rwnx_hw *rwnx_hw);
220
221/**
222 * FW dump handler / trace
223 */
224void rwnx_error_ind(struct rwnx_hw *rwnx_hw);
225void rwnx_umh_done(struct rwnx_hw *rwnx_hw);
226void *rwnx_ipc_fw_trace_desc_get(struct rwnx_hw *rwnx_hw);
227
228#endif /* _RWNX_IPC_UTILS_H_ */
229