1 /***************************************************************************/ /**
2  * @file  sl_si91x_bus.c
3  *******************************************************************************
4  * # License
5  * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
6  *******************************************************************************
7  *
8  * SPDX-License-Identifier: Zlib
9  *
10  * The licensor of this software is Silicon Laboratories Inc.
11  *
12  * This software is provided 'as-is', without any express or implied
13  * warranty. In no event will the authors be held liable for any damages
14  * arising from the use of this software.
15  *
16  * Permission is granted to anyone to use this software for any purpose,
17  * including commercial applications, and to alter it and redistribute it
18  * freely, subject to the following restrictions:
19  *
20  * 1. The origin of this software must not be misrepresented; you must not
21  *    claim that you wrote the original software. If you use this software
22  *    in a product, an acknowledgment in the product documentation would be
23  *    appreciated but is not required.
24  * 2. Altered source versions must be plainly marked as such, and must not be
25  *    misrepresented as being the original software.
26  * 3. This notice may not be removed or altered from any source distribution.
27  *
28  ******************************************************************************/
29 #include "sl_status.h"
30 #include "sl_si91x_types.h"
31 #include "system_si91x.h"
32 #include "rsi_m4.h"
33 #include "sl_constants.h"
34 #include "cmsis_os2.h"
35 #include "rsi_power_save.h"
36 #include "sl_si91x_host_interface.h"
37 #include <stddef.h>
38 #include <stdlib.h>
39 #include "sl_rsi_utility.h"
40 
41 rsi_m4ta_desc_t tx_desc[2];
42 rsi_m4ta_desc_t rx_desc[2];
43 sl_si91x_buffer_queue_t sli_ahb_bus_rx_queue;
44 
45 /******************************************************
46  * *               Function Declarations
47  * ******************************************************/
48 sl_status_t sli_si91x_submit_rx_pkt(void);
49 void sli_submit_rx_buffer(void);
50 void sli_si91x_raise_pkt_pending_interrupt_to_ta(void);
51 
sl_si91x_bus_init(void)52 sl_status_t sl_si91x_bus_init(void)
53 {
54   sli_ahb_bus_rx_queue.head = NULL;
55   sli_ahb_bus_rx_queue.tail = NULL;
56   mask_ta_interrupt(TA_RSI_BUFFER_FULL_CLEAR_EVENT);
57   return RSI_SUCCESS;
58 }
59 
60 /**
61  * @fn          sl_status_t sli_si91x_submit_rx_pkt(void)
62  * @brief       Submit receiver packets
63  * @param[in]   None
64  * @return      0 - Success \n
65  *          Non-Zero - Failure
66  */
67 sl_wifi_buffer_t *rx_pkt_buffer;
sli_si91x_submit_rx_pkt(void)68 sl_status_t sli_si91x_submit_rx_pkt(void)
69 {
70   sl_status_t status;
71   uint16_t data_length = 0;
72   sl_si91x_packet_t *packet;
73   int8_t *pkt_buffer = NULL;
74 
75   if (M4SS_P2P_INTR_SET_REG & RX_BUFFER_VALID) {
76     return -2;
77   }
78 
79   // Allocate packet to receive packet from module
80   status = sl_si91x_host_allocate_buffer(&rx_pkt_buffer, SL_WIFI_RX_FRAME_BUFFER, 1616, 1000);
81   if (status != SL_STATUS_OK) {
82     SL_DEBUG_LOG("\r\n HEAP EXHAUSTED DURING ALLOCATION \r\n");
83     BREAKPOINT();
84   }
85 
86   packet     = sl_si91x_host_get_buffer_data(rx_pkt_buffer, 0, &data_length);
87   pkt_buffer = (int8_t *)&packet->desc[0];
88 
89   // Fill source address in the TX descriptors
90   rx_desc[0].addr = (M4_MEMORY_OFFSET_ADDRESS + (uint32_t)pkt_buffer);
91 
92   // Fill source address in the TX descriptors
93   rx_desc[0].length = 16;
94 
95   // Fill source address in the TX descriptors
96   rx_desc[1].addr = (M4_MEMORY_OFFSET_ADDRESS + (uint32_t)(pkt_buffer + 16));
97 
98   // Fill source address in the TX descriptors
99   rx_desc[1].length = 1600;
100 
101   raise_m4_to_ta_interrupt(RX_BUFFER_VALID);
102 
103   return SL_STATUS_OK;
104 }
105 
sl_si91x_bus_read_frame(sl_wifi_buffer_t ** buffer)106 sl_status_t sl_si91x_bus_read_frame(sl_wifi_buffer_t **buffer)
107 {
108   sl_status_t status = sli_si91x_remove_from_queue(&sli_ahb_bus_rx_queue, buffer);
109   VERIFY_STATUS_AND_RETURN(status);
110 
111   return SL_STATUS_OK;
112 }
113 
114 /**
115  * @fn          sl_status_t sl_si91x_bus_write_frame(sl_si91x_packet_t *packet,
116  *                  uint8_t *payloadparam, uint16_t size_param)
117  * @brief       writing a command to the module.
118  * @param[in]   payloadparam - pointer to the command payload parameter structure
119  * @param[in]   size_param - size of the payload for the command
120  * @return      0              - Success \n
121  *              Negative Value - Failure
122  */
123 
sl_si91x_bus_write_frame(sl_si91x_packet_t * packet,const uint8_t * payloadparam,uint16_t size_param)124 sl_status_t sl_si91x_bus_write_frame(sl_si91x_packet_t *packet, const uint8_t *payloadparam, uint16_t size_param)
125 {
126 
127   // Fill source address in the TX descriptors
128   tx_desc[0].addr = (M4_MEMORY_OFFSET_ADDRESS + (uint32_t)&packet->desc[0]);
129 
130   // Fill source address in the TX descriptors
131   tx_desc[0].length = 16;
132 
133   // Fill source address in the TX descriptors
134   tx_desc[1].addr = (M4_MEMORY_OFFSET_ADDRESS + (uint32_t)payloadparam);
135 
136   // Fill source address in the TX descriptors
137   tx_desc[1].length = size_param;
138 
139   sli_si91x_raise_pkt_pending_interrupt_to_ta();
140 
141   return SL_STATUS_OK;
142 }
143 
sli_submit_rx_buffer(void)144 void sli_submit_rx_buffer(void)
145 {
146   mask_ta_interrupt(RX_PKT_TRANSFER_DONE_INTERRUPT);
147 
148   //! submit to NWP submit packet
149   sli_si91x_submit_rx_pkt();
150 
151   unmask_ta_interrupt(RX_PKT_TRANSFER_DONE_INTERRUPT);
152 }
153 
154 /**
155  * @fn           void rsi_update_tx_dma_desc(uint8 skip_dma_valid)
156  * @brief        This function updates the TX DMA descriptor address
157  * @param[in]    skip_dma_valid
158  * @param[out]   none
159  * @return       none
160  * @section description
161  * This function updates the TX DMA descriptor address
162  *
163  *
164  */
165 
rsi_update_tx_dma_desc(uint8_t skip_dma_valid)166 void rsi_update_tx_dma_desc(uint8_t skip_dma_valid)
167 {
168   if (!skip_dma_valid
169 #ifdef SLI_SI91X_MCU_COMMON_FLASH_MODE
170       && !(M4_ULP_SLP_STATUS_REG & MCU_ULP_WAKEUP)
171 #endif
172   ) {
173     while (M4_TX_DMA_DESC_REG & DMA_DESC_REG_VALID)
174       ;
175   }
176   M4_TX_DMA_DESC_REG = (uint32_t)&tx_desc;
177 }
178 
179 /*==============================================*/
180 /**
181  * @fn           void rsi_update_rx_dma_desc()
182  * @brief        This function updates the RX DMA descriptor address
183  * @param[in]    none
184  * @param[out]   none
185  * @return       none
186  * @section description
187  * This function updates the RX DMA descriptor address
188  *
189  *
190  */
rsi_update_rx_dma_desc(void)191 void rsi_update_rx_dma_desc(void)
192 {
193   M4_RX_DMA_DESC_REG = (uint32_t)&rx_desc;
194 }
195 
sli_si91x_config_m4_dma_desc_on_reset(void)196 void sli_si91x_config_m4_dma_desc_on_reset(void)
197 {
198 
199   //! Wait for NWP to wakeup and should be in bootloader
200   while (!(P2P_STATUS_REG & TA_is_active))
201     ;
202   SL_DEBUG_LOG("\r\nTA is in active state\r\n");
203   //! TBD Need to address why soft reset expecting delay
204   osDelay(100);
205   //! Update M4 Tx and Rx DMA descriptors
206   M4_TX_DMA_DESC_REG = (uint32_t)&tx_desc;
207   M4_RX_DMA_DESC_REG = (uint32_t)&rx_desc;
208 }
209