• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef _WIFI_IPC_HOST_H
16 #define _WIFI_IPC_HOST_H
17 
18 #include "wifi_ipc_shared.h"
19 #if defined(CFG_DEVICE_IPC)
20 #include "devipc_cmd.h"
21 #endif
22 
23 enum ipc_host_desc_status
24 {
25     /// Descriptor is IDLE
26     IPC_HOST_DESC_IDLE      = 0,
27     /// Data can be forwarded
28     IPC_HOST_DESC_FORWARD,
29     /// Data has to be kept in UMAC memory
30     IPC_HOST_DESC_KEEP,
31     /// Delete stored packet
32     IPC_HOST_DESC_DELETE,
33     /// Update Frame Length status
34     IPC_HOST_DESC_LEN_UPDATE,
35     /// Update Frame Length + Length field inside Ethernet Header status
36     IPC_HOST_DESC_ETH_LEN_UPDATE,
37 };
38 
39 /*
40  * TYPE DECLARATION
41  ****************************************************************************************
42  */
43 
44 /**
45  ****************************************************************************************
46  * @brief This structure is used to initialize the MAC SW
47  *
48  * The WLAN device driver provides functions call-back with this structure
49  ****************************************************************************************
50  */
51 struct ipc_irq_elem
52 {
53     uint32_t    status;     ///< Status of the irq
54     uint32_t    param;     ///< param of the irq
55 };
56 
57 struct ipc_txcfm
58 {
59     uint32_t    hostid;     ///< Pre-allocated packet ID from the OS (skbuff on Linux)
60     uint32_t    status;     ///< Status of the transmission
61 };
62 
63 struct ipc_host_cb_tag
64 {
65     /// WLAN driver call-back function: send_data_cfm
66     int (*send_data_cfm)(void *pthis, void* host_id);
67 
68     /// WLAN driver call-back function: recv_data_ind
69     uint8_t (*recv_data_ind)(void *pthis, void* host_id);
70 
71     /// WLAN driver call-back function: recv_msg_ind
72     int8_t (*recv_msg_ind)(void *pthis, void* host_id);
73 
74 #if NX_UF_EN
75     /// WLAN driver call-back function: recv_unsup_rx_vec_ind
76     uint8_t (*recv_unsup_rx_vec_ind)(void *pthis, void *host_id);
77 #endif /* NX_UF_EN */
78 
79     /// WLAN driver call-back function: recv_msgack_ind
80     uint8_t (*recv_msgack_ind)(void *pthis, void* host_id);
81 
82     /// WLAN driver call-back function: recv_dbg_ind
83     //uint8_t (*recv_dbg_ind)(void *pthis, uint32_t host_id);
84 
85     /// WLAN driver call-back function: prim_tbtt_ind
86     //void (*prim_tbtt_ind)(void *pthis);
87 
88     /// WLAN driver call-back function: sec_tbtt_ind
89     //void (*sec_tbtt_ind)(void *pthis);
90 
91 };
92 
93 /*
94  * Struct used to store information about host buffers (DMA Address and local pointer)
95  */
96 struct ipc_hostbuf
97 {
98     uint32_t hostid;      ///< ptr to hostbuf client (ipc_host client) structure
99     uint32_t dma_addr;    ///< ptr to real hostbuf dma address
100 };
101 
102 /*
103  * Struct used to store information about host descriptors (DMA Address and local pointer)
104  */
105 struct ipc_hostdesc
106 {
107     uint32_t dma_addr;    ///< ptr to real hostbuf dma address
108 };
109 
110 /// Definition of the IPC Host environment structure.
111 struct ipc_host_env_tag
112 {
113     /// Structure containing the callback pointers
114     struct ipc_host_cb_tag cb;
115 
116     /// Pointer to the shared environment
117     struct ipc_shared_env_tag *shared;
118 
119     // Store the number of E2A MSG buffers
120     uint32_t ipc_e2amsg_bufnb;
121     // Store the size of the E2A MSG buffers
122     uint32_t ipc_e2amsg_bufsz;
123 
124     /// E2A ACKs of A2E MSGs
125     uint8_t msga2e_cnt;
126     uint32_t msga2e_hostid;
127 
128     uint32_t ipc_tx_offset;
129     /// Pointer to the attached object (used in callbacks and register accesses)
130     void *pthis;
131 };
132 
133 /**
134  ****************************************************************************************
135  * @brief Initialize the IPC running on the Application CPU.
136  *
137  * This function:
138  *   - initializes the IPC software environments
139  *   - enables the interrupts in the IPC block
140  *
141  * @param[in]   env   Pointer to the IPC host environment
142  *
143  * @warning Since this function resets the IPC Shared memory, it must be called before
144  * the LMAC FW is launched because LMAC sets some init values in IPC Shared memory at boot.
145  *
146  ****************************************************************************************
147  */
148 void ipc_host_init(struct ipc_host_env_tag *env,
149                   struct ipc_host_cb_tag *cb,
150                   struct ipc_shared_env_tag *shared_env_ptr,
151                   void *pthis);
152 
153 
154 /**
155  ****************************************************************************************
156  * @brief Retrieve a new free Tx descriptor (host side).
157  *
158  * This function returns a pointer to the next Tx descriptor available from the queue
159  * queue_idx to the host driver. The driver will have to fill it with the
160  * appropriate endianness and to send it to the
161  * emb side with ipc_host_txdesc_push().
162  *
163  * This function should only be called once until ipc_host_txdesc_push() is called.
164  *
165  * This function will return NULL if the queue is full.
166  *
167  * @param[in]   env   Pointer to the IPC host environment
168  * @param[in]   queue_idx   Queue index. The index can be inferred from the user priority
169  *                          of the incoming packet.
170  * @return                  Pointer to the next Tx descriptor free. This can point to
171  *                          the host memory or to shared memory, depending on IPC
172  *                          implementation.
173  *
174  ****************************************************************************************
175  */
176 volatile struct txdesc_host *ipc_host_txdesc_get(struct ipc_host_env_tag *env,
177                                                  const int queue_idx);
178 
179 
180 /**
181  ****************************************************************************************
182  * @brief Push a filled Tx descriptor (host side).
183  *
184  * This function sets the next Tx descriptor available by the host side:
185  * - as used for the host side
186  * - as available for the emb side.
187  * The Tx descriptor must be correctly filled before calling this function.
188  *
189  * This function may trigger an IRQ to the emb CPU depending on the interrupt
190  * mitigation policy and on the push count.
191  *
192  * @param[in]   queue_idx   Queue index. Same value than ipc_host_txdesc_get()
193  *
194  ****************************************************************************************
195  */
196 void ipc_host_txdesc_push(const int queue_idx);
197 
198 
199 /**
200  ****************************************************************************************
201  * @brief Push a pre-allocated buffer descriptor for Rx packet (host side)
202  *
203  * This function should be called by the host IRQ handler to supply the embedded
204  * side with new empty buffer.
205  *
206  * @param[in]   env         Pointer to the IPC host environment
207  * @param[in]   hostid      Packet ID used by the host (skbuff pointer on Linux)
208  * @param[in]   hostbuf     Pointer to the start of the buffer payload in the
209  *                          host memory (this may be inferred from the skbuff?)
210  *                          The length of this buffer should be predefined
211  *                          between host and emb statically (constant needed?).
212  *
213  ****************************************************************************************
214  */
215 int ipc_host_rxbuf_push(struct ipc_host_env_tag *env, uint32_t hostid, uint32_t hostbuf);
216 
217 
218 /**
219  ****************************************************************************************
220  * @brief Push a pre-allocated buffer descriptor for MSGs (host side)
221  *
222  * This function is only called at Init time since the MSGs will be handled directly and
223  * buffer can be re-used as soon as the message is handled, no need to re-allocate new
224  * buffers in the meantime.
225  *
226  * @param[in]   env         Pointer to the IPC host environment
227  * @param[in]   hostid      Packet ID used by the host (skbuff pointer on Linux)
228  * @param[in]   hostbuf     Pointer to the start of the buffer payload in the
229  *                          host memory.
230  *                          The length of this buffer should be predefined
231  *                          between host and emb statically.
232  *
233  ****************************************************************************************
234  */
235 int ipc_host_msgbuf_push(struct ipc_host_env_tag *env, void *hostid,
236                                                        uint32_t hostbuf);
237 
238 /**
239  ****************************************************************************************
240  * @brief Push a pre-allocated buffer descriptor for Debug messages (host side)
241  *
242  * This function is only called at Init time since the Debug messages will be handled directly and
243  * buffer can be re-used as soon as the message is handled, no need to re-allocate new
244  * buffers in the meantime.
245  *
246  * @param[in]   env         Pointer to the IPC host environment
247  * @param[in]   hostid      Packet ID used by the host (skbuff pointer on Linux)
248  * @param[in]   hostbuf     Pointer to the start of the buffer payload in the
249  *                          host memory.
250  *                          The length of this buffer should be predefined
251  *                          between host and emb statically.
252  *
253  ****************************************************************************************
254  */
255 int ipc_host_dbgbuf_push(struct ipc_host_env_tag *env, uint32_t hostid,
256                                                        uint32_t hostbuf);
257 
258 /**
259  ****************************************************************************************
260  * @brief Push the pre-allocated logic analyzer and debug information buffer
261  *
262  * @param[in]   env         Pointer to the IPC host environment
263  * @param[in]   infobuf     Pointer to the start of the buffer payload in the
264  *                          host memory.
265  *                          The length of this buffer should be predefined
266  *                          between host and emb statically.
267  *
268  ****************************************************************************************
269  */
270 void ipc_host_dbginfobuf_push(struct ipc_host_env_tag *env, uint32_t infobuf);
271 
272 
273 /**
274  ****************************************************************************************
275  * @brief Handle all IPC interrupts on the host side.
276  *
277  * The following interrupts should be handled:
278  * Tx confirmation, Rx buffer requests, Rx packet ready and kernel messages
279  *
280  * @param[in]   env   Pointer to the IPC host environment
281  *
282  ****************************************************************************************
283  */
284 void ipc_host_irq(struct ipc_host_env_tag *env, struct ipc_irq_elem *elem);
285 
286 /**
287  ****************************************************************************************
288  * @brief Handler for kernel message called from general IRQ handler
289  *
290  * @param[in]   env      pointer to the IPC Host environment
291  ****************************************************************************************
292  */
293 void ipc_host_msg_handler(struct ipc_host_env_tag *env);
294 
295 /**
296  ****************************************************************************************
297  * @brief Send a message to the embedded side
298  *
299  * @param[in]   env      Pointer to the IPC host environment
300  * @param[in]   msg_buf  Pointer to the message buffer
301  * @param[in]   msg_len  Length of the message to be transmitted
302  *
303  * @return      Non-null value on failure
304  *
305  ****************************************************************************************
306  */
307 int ipc_host_msg_push(struct ipc_host_env_tag *env, void *msg_buf, uint16_t len);
308 
309 #if defined(CFG_DEVICE_IPC)
310 void devipc_custom_msg_push(struct dbg_custom_msg_cfm *cfm);
311 #endif
312 
313 /**
314  ****************************************************************************************
315  * @brief Enable IPC interrupts
316  *
317  * @param[in]   env  Global ipc_host environment pointer
318  * @param[in]   value  Bitfield of the interrupts to enable
319  *
320  * @warning After calling this function, IPC interrupts can be triggered at any time.
321  * Potentially, an interrupt could happen even before returning from the function if
322  * there is a request pending from the embedded side.
323  *
324  ****************************************************************************************
325  */
326 void ipc_host_enable_irq(struct ipc_host_env_tag *env, uint32_t value);
327 
328 uint32_t ipc_host_get_status(void);
329 uint32_t ipc_host_get_rawstatus(void);
330 #if NX_UF_EN
331 int ipc_host_unsup_rx_vec_buf_push(struct ipc_host_env_tag *env, void *hostid, uint32_t hostbuf);
332 #endif /* NX_UF_EN */
333 uint8_t wifi_sleep_level_get(void);
334 
335 #endif // _WIFI_IPC_HOST_H
336