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_SHARED_H 16 #define _WIFI_IPC_SHARED_H 17 18 /** 19 **************************************************************************************** 20 * @defgroup IPC IPC 21 * @ingroup PLATFORM_DRIVERS 22 * @brief Inter Processor Communication module. 23 * 24 * The IPC module implements the protocol to communicate between the Host CPU 25 * and the Embedded CPU. 26 * 27 * A typical use case of the IPC Tx path API: 28 * @msc 29 * hscale = "2"; 30 * 31 * a [label=Driver], 32 * b [label="IPC host"], 33 * c [label="IPC emb"], 34 * d [label=Firmware]; 35 * 36 * --- [label="Tx descriptor queue example"]; 37 * a=>a [label="Driver receives a Tx packet from OS"]; 38 * a=>b [label="ipc_host_txdesc_get()"]; 39 * a<<b [label="struct txdesc_host *"]; 40 * a=>a [label="Driver fill the descriptor"]; 41 * a=>b [label="ipc_host_txdesc_push()"]; 42 * ... [label="(several Tx desc can be pushed)"]; 43 * b:>c [label="Tx desc queue filled IRQ"]; 44 * c=>>d [label="IPC emb Tx desc callback"]; 45 * ... [label="(several Tx desc can be popped)"]; 46 * d=>d [label="Packets are sent or discarded"]; 47 * --- [label="Tx confirm queue example"]; 48 * c<=d [label="ipc_emb_txcfm_push()"]; 49 * c>>d [label="Request accepted"]; 50 * ... [label="(several Tx cfm can be pushed)"]; 51 * b<:c [label="Tx cfm queue filled IRQ"]; 52 * a<<=b [label="Driver's Tx Confirm callback"]; 53 * a=>b [label="ipc_host_txcfm_pop()"]; 54 * a<<b [label="struct ipc_txcfm"]; 55 * a<=a [label="Packets are freed by the driver"]; 56 * @endmsc 57 * 58 * A typical use case of the IPC Rx path API: 59 * @msc 60 * hscale = "2"; 61 * 62 * a [label=Firmware], 63 * b [label="IPC emb"], 64 * c [label="IPC host"], 65 * d [label=Driver]; 66 * 67 * --- [label="Rx buffer and desc queues usage example"]; 68 * d=>c [label="ipc_host_rxbuf_push()"]; 69 * d=>c [label="ipc_host_rxbuf_push()"]; 70 * d=>c [label="ipc_host_rxbuf_push()"]; 71 * ... [label="(several Rx buffer are pushed)"]; 72 * a=>a [label=" Frame is received\n from the medium"]; 73 * a<<b [label="struct ipc_rxbuf"]; 74 * a=>a [label=" Firmware fill the buffer\n with received frame"]; 75 * a<<b [label="Push accepted"]; 76 * ... [label="(several Rx desc can be pushed)"]; 77 * b:>c [label="Rx desc queue filled IRQ"]; 78 * c=>>d [label="Driver Rx packet callback"]; 79 * c<=d [label="ipc_host_rxdesc_pop()"]; 80 * d=>d [label="Rx packet is handed \nover to the OS "]; 81 * ... [label="(several Rx desc can be poped)"]; 82 * --- [label="Rx buffer request exemple"]; 83 * b:>c [label="Low Rx buffer count IRQ"]; 84 * a<<b [label="struct ipc_rxbuf"]; 85 * c=>>d [label="Driver Rx buffer callback"]; 86 * d=>c [label="ipc_host_rxbuf_push()"]; 87 * d=>c [label="ipc_host_rxbuf_push()"]; 88 * d=>c [label="ipc_host_rxbuf_push()"]; 89 * ... [label="(several Rx buffer are pushed)"]; 90 * @endmsc 91 * 92 * @{ 93 **************************************************************************************** 94 */ 95 96 /* 97 * INCLUDE FILES 98 **************************************************************************************** 99 */ 100 #include "wb_co_int.h" 101 #include "wifi_tx_swdesc.h" 102 #include "rwnx_config.h" 103 104 /* 105 * DEFINES AND MACROS 106 **************************************************************************************** 107 */ 108 /// Number of IPC TX queues 109 #define IPC_TXQUEUE_CNT NX_TXQ_CNT 110 111 /// Number of Host buffers available for Data Rx handling (through DMA) 112 #ifdef CFG_HS_IPERF 113 #define IPC_RXBUF_CNT 25 114 #else 115 #define IPC_RXBUF_CNT 11 116 #endif 117 118 #define IPC_TXBUF_CNT 32 119 120 //memory addr: 0x190800 (30K) 121 #define IPC_FW_TXBUF_CNT 17 122 123 /// Number of shared descriptors available for Data RX handling 124 #define IPC_RXDESC_CNT 32 125 126 /// Number of Host buffers available for Radar events handling (through DMA) 127 #define IPC_RADARBUF_CNT 16 128 129 ///Number of Host buffers available for unsupported rx vector handling (through DMA) 130 #define IPC_UNSUPRXVECBUF_CNT 8 131 132 #define IPC_MSGE2A_BUF_CNT 8 133 134 /// Length used in APP2EMB MSGs structures 135 #ifdef CFG_RWTL 136 #define IPC_A2E_MSG_BUF_SIZE 127 // size in 4-byte words 137 #else 138 #define IPC_A2E_MSG_BUF_SIZE 127 // size in 4-byte words 139 #endif 140 141 /// Length required in EMB2APP MSGs structures, for non-TL4 case 142 #define IPC_E2A_MSG_SIZE_BASE 256//15 // size in 4-byte words 143 144 /// Length used in EMB2APP MSGs structures, including the potential overhead for TL4 145 #ifdef CFG_RWTL 146 #define IPC_E2A_MSG_PARAM_SIZE (IPC_E2A_MSG_SIZE_BASE + (IPC_E2A_MSG_SIZE_BASE / 2)) 147 #else 148 #define IPC_E2A_MSG_PARAM_SIZE IPC_E2A_MSG_SIZE_BASE 149 #endif 150 151 /// Define used for Rx hostbuf validity. 152 /// This value should appear only when hostbuf was used for a Reception. 153 #define RX_DMA_OVER_PATTERN 0xAAAAAA00 154 155 /** 156 * Define used for MSG buffers validity. 157 * This value will be written only when a MSG buffer is used for sending from Emb to App. 158 */ 159 #define IPC_MSGE2A_VALID_PATTERN 0xADDEDE2A 160 161 /// Message structure for MSGs from Emb to App 162 struct ipc_e2a_msg 163 { 164 uint16_t id; ///< Message id. 165 uint16_t dummy_dest_id; ///< Not used 166 uint16_t dummy_src_id; ///< Not used 167 uint16_t param_len; ///< Parameter embedded struct length. 168 169 uint32_t pattern; ///< Used to stamp a valid MSG buffer 170 uint32_t param[IPC_E2A_MSG_PARAM_SIZE]; ///< Parameter embedded struct. Must be word-aligned. 171 }; 172 173 /// Message structure for MSGs from App to Emb. 174 /// Actually a sub-structure will be used when filling the messages. 175 struct ipc_a2e_msg 176 { 177 uint32_t dummy_word; ///< used to cope with kernel message structure 178 uint32_t msg[IPC_A2E_MSG_BUF_SIZE]; ///< body of the msg 179 }; 180 181 /// Information provided by host to indentify RX buffer 182 struct ipc_shared_rx_buf 183 { 184 /// ptr to hostbuf client (ipc_host client) structure 185 uint32_t hostid; 186 /// ptr to real hostbuf dma address 187 uint32_t dma_addr; 188 }; 189 190 /// Information provided by host to indentify RX desc 191 struct ipc_shared_rx_desc 192 { 193 /// DMA Address 194 uint32_t dma_addr; 195 }; 196 197 #ifdef CFG_DEVICE_IPC 198 typedef struct { 199 struct co_list_hdr list_hdr; 200 uint32_t msg_data[1]; 201 } devipc_custmsg_node_t; 202 #endif 203 204 /* 205 * TYPE and STRUCT DEFINITIONS 206 **************************************************************************************** 207 */ 208 // Indexes are defined in the MIB shared structure 209 /// Structure describing the IPC data shared with the host CPU 210 struct ipc_shared_env_tag 211 { 212 ///FW characteristics 213 //volatile struct compatibility_tag comp_info; 214 215 /// AP MGMT TX Status 216 uint32_t statinfo; 217 218 /// Room for MSG to be sent from App to Emb 219 volatile struct ipc_a2e_msg msg_a2e_buf; 220 221 /// Room to build the Emb->App MSGs Xferred 222 //volatile struct ipc_e2a_msg msg_e2a_buf; 223 224 /// Host buffer addresses for Emb->App MSGs DMA Xfers 225 struct co_list msg_e2a_hostbuf_free_list; 226 struct co_list msg_e2a_hostbuf_post_list; 227 228 #if NX_RADAR_DETECT 229 /// Host buffer addresses for the radar events 230 volatile uint32_t radarbuf_hostbuf [IPC_RADARBUF_CNT]; // buffers @ for Radar Events 231 #endif 232 233 #if NX_UF_EN 234 /// Host buffer addresses for the unsupported rx vectors 235 struct co_list uf_e2a_hostbuf_free_list; 236 struct co_list uf_e2a_hostbuf_post_list; 237 #endif /* NX_UF_EN */ 238 239 /// RX Descriptors Array 240 //volatile struct ipc_shared_rx_desc host_rxdesc[IPC_RXDESC_CNT]; 241 /// RX Buffers Array 242 struct co_list rx_e2a_hostbuf_free_list; 243 struct co_list rx_e2a_hostbuf_post_list; 244 245 struct co_list a2e_tx_mem_free_list; 246 struct co_list a2e_tx_mem_post_list; 247 volatile uint32_t a2e_adjlen; // adjust len for app2emb pkt buf 248 249 #if defined(CFG_DEVICE_IPC) 250 struct co_list e2a_cust_msg_free_list; 251 struct co_list e2a_cust_msg_post_list; 252 struct co_list a2e_cust_msg_free_list; 253 struct co_list a2e_cust_msg_post_list; 254 #endif 255 }; 256 257 /// IPC Shared environment 258 extern struct ipc_shared_env_tag ipc_shared_env; 259 260 /// 261 struct rxdesc_tag 262 { 263 /// Host Buffer Address 264 uint32_t host_id; 265 /// Length 266 uint32_t frame_len; 267 /// Status 268 uint16_t status; 269 }; 270 271 /* 272 * TYPE and STRUCT DEFINITIONS 273 **************************************************************************************** 274 */ 275 /// @name APP2EMB IPC interrupt definitions 276 /// @{ 277 278 /// Interrupts bits used for the TX descriptors of the AC queues 279 /// IPC TX descriptor interrupt mask 280 #define IPC_IRQ_A2E_TXDESC 0x0F00 281 282 /// IPC APP2EMB power down request interrupt bit 283 #define IPC_IRQ_A2E_PWRDN_REQ CO_BIT(31) 284 /// IPC APP2EMB clock gate request interrupt bit 285 #define IPC_IRQ_A2E_CLKGATE_REQ CO_BIT(30) 286 287 #if defined(CFG_DEVICE_IPC) 288 /// IPC APP2EMB customer message 289 #define IPC_IRQ_A2E_CUSTOM_MSG CO_BIT(13) 290 #endif 291 292 /// First of the IPC TX descriptor interrupts, bit8 ~ bit11 293 #define IPC_IRQ_A2E_TXDESC_FIRSTBIT (8) 294 /// IPC RX buffer allocation interrupt bit 295 #define IPC_IRQ_A2E_RXBUF_BACK CO_BIT(5) 296 /// IPC APP2EMB message interrupt bit 297 #define IPC_IRQ_A2E_MSG CO_BIT(1) 298 /// IPC global interrupt mask 299 #define IPC_IRQ_A2E_ALL (IPC_IRQ_A2E_TXDESC|IPC_IRQ_A2E_MSG) 300 301 /// @} 302 303 /// @name EMB2APP IPC interrupt definitions 304 /// IPC EMB2APP not allow low power interrupt 305 #define IPC_IRQ_E2A_LOWPWR_NOT_ALLOW CO_BIT(31) 306 /// IPC EMB2APP allow low power interrupt 307 #define IPC_IRQ_E2A_LOWPWR_ALLOW CO_BIT(30) 308 309 #if defined(CFG_DEVICE_IPC) 310 /// IPC EMB2APP customer message 311 #define IPC_IRQ_E2A_CUSTOM_MSG CO_BIT(10) 312 #endif 313 314 /// IPC EMB2APP wifi fw idle indication interrupt 315 #define IPC_IRQ_E2A_WIFI_FW_IDLE_IND CO_BIT(9) 316 /// IPC mgmt tx cfm interrupt 317 #define IPC_IRQ_E2A_MGMT_CFM CO_BIT(8) 318 /// IPC unsupported rx vector interrupt 319 #define IPC_IRQ_E2A_UNSUP_RX_VEC CO_BIT(7) 320 /// IPC secondary TBTT interrupt 321 #define IPC_IRQ_E2A_TBTT_SEC CO_BIT(5) 322 /// IPC primary TBTT interrupt 323 #define IPC_IRQ_E2A_TBTT_PRIM CO_BIT(4) 324 /// IPC RX descriptor interrupt 325 #define IPC_IRQ_E2A_RXDESC CO_BIT(3) 326 /// IPC APP2EMB message acknowledgment interrupt 327 #define IPC_IRQ_E2A_MSG_ACK CO_BIT(2) 328 /// IPC EMB2APP message interrupt 329 #define IPC_IRQ_E2A_MSG CO_BIT(1) 330 /// IPC EMB2APP ready interrupt 331 #define IPC_IRQ_EMB_READY CO_BIT(0) 332 /// IPC EMB2APP global interrupt mask 333 #if defined(CFG_DEVICE_IPC) 334 #define IPC_IRQ_WIFI_E2A_ALL ( IPC_IRQ_E2A_RXDESC \ 335 | IPC_IRQ_E2A_MSG_ACK \ 336 | IPC_IRQ_E2A_MSG \ 337 | IPC_IRQ_EMB_READY \ 338 | IPC_IRQ_E2A_MGMT_CFM \ 339 | IPC_IRQ_E2A_UNSUP_RX_VEC \ 340 | IPC_IRQ_E2A_WIFI_FW_IDLE_IND \ 341 | IPC_IRQ_E2A_CUSTOM_MSG \ 342 | IPC_IRQ_E2A_LOWPWR_ALLOW) 343 #else 344 #define IPC_IRQ_WIFI_E2A_ALL ( IPC_IRQ_E2A_RXDESC \ 345 | IPC_IRQ_E2A_MSG_ACK \ 346 | IPC_IRQ_E2A_MSG \ 347 | IPC_IRQ_EMB_READY \ 348 | IPC_IRQ_E2A_MGMT_CFM \ 349 | IPC_IRQ_E2A_UNSUP_RX_VEC \ 350 | IPC_IRQ_E2A_WIFI_FW_IDLE_IND \ 351 | IPC_IRQ_E2A_LOWPWR_ALLOW) 352 #endif 353 354 #endif // _WIFI_IPC_SHARED_H 355 356