1 /*! *********************************************************************************
2 * Copyright 2021-2025 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 ********************************************************************************** */
8 
9 #include "EmbeddedTypes.h"
10 #include "PhyInterface.h"
11 #include "Phy.h"
12 
13 #include "fsl_adapter_rpmsg.h"
14 #include "fsl_os_abstraction.h"
15 #include "fwk_platform.h"
16 #if defined(HDI_MODE) && (HDI_MODE == 1)
17 #include "hdi.h"
18 #endif
19 #if (defined(HWINIT_DEBUG_DTEST) && (HWINIT_DEBUG_DTEST == 1L))
20 #include "dtest.h"
21 #endif
22 
23 #ifdef MEM_USE_ZEPHYR
24 #include <zephyr/kernel.h>
25 
26 #define PHY_MSG_Alloc(x) k_malloc(x)
27 #define PHY_MSG_Free(x) k_free(x)
28 
29 #else	/* MEM_USE_ZEPHYR */
30 #include "fsl_component_messaging.h"
31 
32 #define PHY_MSG_Alloc(x) MSG_Alloc(x)
33 #define PHY_MSG_Free(x) MSG_Free(x)
34 #endif	/* MEM_USE_ZEPHYR */
35 
36 #undef CTX_NO
37 #define CTX_NO 2
38 
39 static struct phy_local
40 {
41     uint32_t id;
42 
43     PD_MAC_SapHandler_t         PD_MAC_SapHandler;
44     PLME_MAC_SapHandler_t       PLME_MAC_SapHandler;
45 } phyLocal[CTX_NO];
46 
47 static RPMSG_HANDLE_DEFINE(phyRpmsgHandle);
48 static hal_rpmsg_config_t phyRpmsgConfig = {
49     .local_addr  = 10,
50     .remote_addr = 20,
51 #if defined(RW610_SERIES)
52     .imuLink     = kIMU_LinkCpu2Cpu3
53 #endif
54 };
55 
56 static uint8_t wait_phy_rsp = FALSE;
57 static plmeGetReq_t phy_get_rsp;
58 
59 static OSA_EVENT_HANDLE_DEFINE(get_event);
60 
61 static bool_t phy_intf_init_done = FALSE;
62 static bool_t phy_intf_init_ongoing = FALSE;
63 
64 
wait_response()65 static void wait_response()
66 {
67     osa_event_flags_t flags;
68     uint32_t dt = osaWaitForever_c;
69 
70     if (!OSA_TaskGetCurrentHandle())
71     {
72         /* Current task is valid in OSA_ProcessTasks().
73            There is no check in OSA_EventWait() that current task is valid.
74            For osaWaitNone_c, current task is not used */
75         dt = osaWaitNone_c;
76     }
77 
78     /* Wait until NBU delivers result over RPMSG */
79     while (OSA_EventWait(get_event, 1, 1, dt, &flags) != KOSA_StatusSuccess)
80     {}
81 
82     /* Clear event as auto clear is not enabled */
83     OSA_EventClear(get_event, 1);
84 }
85 
86 
PhyRpmsgRxCallback(void * param,uint8_t * data,uint32_t len)87 static hal_rpmsg_return_status_t PhyRpmsgRxCallback(void *param, uint8_t *data, uint32_t len)
88 {
89     (void)param;
90     phyMessageHeader_t *pMsg = (phyMessageHeader_t *)data;
91 
92     if (pMsg->msgType == gPlmeGetReq_c)
93     {
94         if (wait_phy_rsp)
95         {
96             phy_get_rsp = ((macToPlmeMessage_t *)pMsg)->msgData.getReq;
97 
98             OSA_EventSet(get_event, 1);
99         }
100         return kStatus_HAL_RL_RELEASE;
101     }
102 
103     pMsg = (phyMessageHeader_t *)PHY_MSG_Alloc(len);
104     if (!pMsg)
105     {
106         return kStatus_HAL_RL_RELEASE;
107     }
108     memcpy(pMsg, data, len);
109 
110     if (pMsg->ctx_id >= CTX_NO)
111     {
112         pMsg->ctx_id = 0;
113     }
114 
115     switch(pMsg->msgType)
116     {
117         case gPdDataInd_c:
118             ((pdDataToMacMessage_t *)pMsg)->msgData.dataInd.pPsdu = (uint8_t *)pMsg + sizeof(pdDataToMacMessage_t);
119 
120             phyLocal[pMsg->ctx_id].PD_MAC_SapHandler((pdDataToMacMessage_t *)pMsg, pMsg->ctx_id);
121             break;
122 
123         case gPdDataCnf_c:
124             ((pdDataToMacMessage_t *)pMsg)->msgData.dataCnf.ackData = (uint8_t *)pMsg + sizeof(pdDataToMacMessage_t);
125 
126             phyLocal[pMsg->ctx_id].PD_MAC_SapHandler((pdDataToMacMessage_t *)pMsg, pMsg->ctx_id);
127             break;
128 
129         case gPlmeCcaCnf_c:
130         case gPlmeEdCnf_c:
131         case gPlmeSetTRxStateCnf_c:
132         case gPlmeSetCnf_c:
133         case gPlmeTimeoutInd_c:
134         case gPlmeAbortInd_c:
135             phyLocal[pMsg->ctx_id].PLME_MAC_SapHandler((plmeToMacMessage_t *)pMsg, pMsg->ctx_id);
136             break;
137 
138         default:
139             PHY_MSG_Free(pMsg);
140     }
141 
142     return kStatus_HAL_RL_RELEASE;
143 }
144 
Phy_Init(void)145 void Phy_Init(void)
146 {
147     OSA_InterruptDisable();
148 
149     if (phy_intf_init_done || phy_intf_init_ongoing)
150     {
151         OSA_InterruptEnable();
152         return;
153     }
154 
155     phy_intf_init_ongoing = TRUE;
156 
157     OSA_InterruptEnable();
158 
159     if (HAL_RpmsgInit((hal_rpmsg_handle_t)phyRpmsgHandle, &phyRpmsgConfig) != kStatus_HAL_RpmsgSuccess)
160     {
161         assert(0);
162         return;
163     }
164 
165     if (HAL_RpmsgInstallRxCallback((hal_rpmsg_handle_t)phyRpmsgHandle, PhyRpmsgRxCallback, NULL) != kStatus_HAL_RpmsgSuccess)
166     {
167         assert(0);
168         return;
169     }
170 
171     /* plmeEventHandle with 0 auto clear to allow the task to run after flags have been set */
172     OSA_EventCreate((osa_event_handle_t)get_event, 0);
173 
174     /* Configure DTEST signals for debug */
175 #if (defined(HWINIT_DEBUG_DTEST) && (HWINIT_DEBUG_DTEST == 1L))
176     dtest_init(DTEST0 | DTEST1 | DTEST2 | DTEST3 | DTEST4 | DTEST5 | DTEST6 | DTEST7 | DTEST8 | DTEST9 | DTEST10 | DTEST11 | DTEST12 | DTEST13 );
177     dtest_select(0x00); /* Place selftest waveform onto DTEST ports */
178 #endif
179 
180     phy_intf_init_done = TRUE;
181 }
182 
183 /*! *********************************************************************************
184 * \brief  This function registers the MAC PD and PLME SAP handlers
185 *
186 * \param[in]  pPD_MAC_SapHandler   Pointer to the MAC PD handler function
187 * \param[in]  pPLME_MAC_SapHandler Pointer to the MAC PLME handler function
188 * \param[in]  instanceId           The instance of the PHY
189 *
190 * \return  The status of the operation.
191 *
192 ********************************************************************************** */
Phy_RegisterSapHandlers(PD_MAC_SapHandler_t pPD_MAC_SapHandler,PLME_MAC_SapHandler_t pPLME_MAC_SapHandler,instanceId_t instanceId)193 void Phy_RegisterSapHandlers(PD_MAC_SapHandler_t pPD_MAC_SapHandler,
194                              PLME_MAC_SapHandler_t pPLME_MAC_SapHandler,
195                              instanceId_t instanceId)
196 {
197     if (!phy_intf_init_done)
198     {
199         return;
200     }
201 
202     if (instanceId >= CTX_NO)
203     {
204         instanceId = 0;
205     }
206 
207     phyLocal[instanceId].PD_MAC_SapHandler = pPD_MAC_SapHandler;
208     phyLocal[instanceId].PLME_MAC_SapHandler = pPLME_MAC_SapHandler;
209 }
210 
211 /*! *********************************************************************************
212 * \brief  This is the PLME SAP message handler
213 *
214 * \param[in]  pMsg Pointer to the PLME request message
215 * \param[in]  instanceId The instance of the PHY
216 *
217 * \return  phyStatus_t The status of the operation.
218 *
219 ********************************************************************************** */
MAC_PLME_SapHandler(macToPlmeMessage_t * pMsg,instanceId_t phyInstance)220 phyStatus_t MAC_PLME_SapHandler(macToPlmeMessage_t *pMsg, instanceId_t phyInstance)
221 {
222     phyStatus_t ret = gPhySuccess_c;
223     osa_event_flags_t flags;
224 
225     if (!phy_intf_init_done)
226     {
227         return gPhyInvalidParameter_c;
228     }
229 
230     PLATFORM_RemoteActiveReq();
231 
232     do
233     {
234         if (phyInstance >= CTX_NO)
235         {
236             phyInstance = 0;
237         }
238 
239         pMsg->ctx_id = phyInstance;
240 
241         /* Bind Event with current task (main_task usually) in case RPMSG response is faster than
242          * OSA_EventWait in the loop below.
243          */
244         if (pMsg->msgType == gPlmeGetReq_c)
245         {
246             phy_get_rsp.PibAttributeValue = 0;
247 
248             OSA_EventWait(get_event, 1, 1, osaWaitNone_c, &flags);
249             wait_phy_rsp = TRUE;
250         }
251 
252 #if defined(HDI_MODE) && (HDI_MODE == 1)
253         if ((pMsg->msgType == gPlmeSetReq_c) && (pMsg->msgData.setReq.PibAttribute == gPhyPibCurrentChannel_c))
254         {
255             if (pMsg->msgData.setReq.PibAttribute == gPhyPibCurrentChannel_c)
256             {
257                 HDI_SendChannelSwitchCmd((uint32_t)pMsg->msgData.setReq.PibAttributeValue);
258             }
259         }
260 #endif
261 
262         if (HAL_RpmsgSend((hal_rpmsg_handle_t)phyRpmsgHandle, (uint8_t *)pMsg, sizeof(macToPlmeMessage_t)) != kStatus_HAL_RpmsgSuccess)
263         {
264             ret = gPhyBusy_c;
265             break;
266         }
267 
268         if (pMsg->msgType == gPlmeGetReq_c)
269         {
270             wait_response();
271             wait_phy_rsp = FALSE;
272 
273             pMsg->msgData.getReq.PibAttributeValue = phy_get_rsp.PibAttributeValue;
274         }
275     } while(0);
276 
277     wait_phy_rsp = FALSE;
278     PLATFORM_RemoteActiveRel();
279 
280     return ret;
281 }
282 
283 /*! *********************************************************************************
284 * \brief  This is the PD SAP message handler
285 *
286 * \param[in]  pMsg Pointer to the PD request message
287 * \param[in]  instanceId The instance of the PHY
288 *
289 * \return  The status of the operation.
290 *
291 ********************************************************************************** */
MAC_PD_SapHandler(macToPdDataMessage_t * pMsg,instanceId_t phyInstance)292 phyStatus_t MAC_PD_SapHandler(macToPdDataMessage_t *pMsg, instanceId_t phyInstance)
293 {
294     uint32_t len = sizeof(macToPdDataMessage_t);
295     phyStatus_t ret = gPhySuccess_c;
296 
297     if (!phy_intf_init_done)
298     {
299         return gPhyInvalidParameter_c;
300     }
301 
302     PLATFORM_RemoteActiveReq();
303 
304     do
305     {
306         if (phyInstance >= CTX_NO)
307         {
308             phyInstance = 0;
309         }
310 
311         pMsg->ctx_id = phyInstance;
312 
313         if (pMsg->msgType == gPdDataReq_c)
314         {
315             len += pMsg->msgData.dataReq.psduLength;
316         }
317 
318         if (HAL_RpmsgSend((hal_rpmsg_handle_t)phyRpmsgHandle, (uint8_t *)pMsg, len) != kStatus_HAL_RpmsgSuccess)
319         {
320              ret = gPhyBusy_c;
321              break;
322         }
323     } while (0);
324 
325     PLATFORM_RemoteActiveRel();
326 
327     return ret;
328 }
329 
PHY_get_ctx()330 uint8_t PHY_get_ctx()
331 {
332     macToPlmeMessage_t msg;
333 
334     msg.msgType = gPlmeGetReq_c;
335     msg.msgData.getReq.PibAttribute = gPhyGetCtxId;
336     msg.msgData.getReq.PibAttributeValue = (uint64_t)(-1);
337 
338     MAC_PLME_SapHandler(&msg, 0);
339 
340     return (uint8_t)msg.msgData.getReq.PibAttributeValue;
341 }
342 
343 /*! *********************************************************************************
344 * \brief  This function returns the RSSI for the last received packet
345 *
346 * \return  uint8_t  RSSI value
347 *
348 ********************************************************************************** */
PhyGetLastRxRssiValue(void)349 uint8_t PhyGetLastRxRssiValue(void)
350 {
351     int32_t lqi_to_rssi = 0;
352 
353     return (uint8_t)lqi_to_rssi;
354 }
355 
PhyConvertLQIToRSSI(uint8_t lqi)356 int8_t PhyConvertLQIToRSSI(uint8_t lqi)
357 {
358     int32_t rssi = (36 * lqi - 9836) / 109;
359 
360     return (int8_t)rssi;
361 }
362