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