1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - NWM - libraries
3   File:     nwm_system.c
4 
5   Copyright 2007-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 #include <twl.h>
19 #include "nwm_arm9_private.h"
20 #include "nwm_common_private.h"
21 
22 NWMArm9Buf *nwm9buf = NULL;
23 static PMSleepCallbackInfo sleepCbInfo;  //Sleep callback information to register with the PM library
24 
25 #ifdef NWM_SUPPORT_HWRESET
26 PMExitCallbackInfo hwResetCbInfo;
27 #endif
28 
29 static void NwmSleepCallback(void *);
30 
31 /*---------------------------------------------------------------------------*
32   Name:         NWMi_GetSystemWork
33 
34   Description:  Gets a pointer to the start of the buffer used internally by the new WM library.
35 
36   Arguments:    None.
37 
38   Returns:      NWMArm9Buf*: Returns a pointer to the internal work buffer.
39  *---------------------------------------------------------------------------*/
NWMi_GetSystemWork(void)40 NWMArm9Buf *NWMi_GetSystemWork(void)
41 {
42 //    SDK_NULL_ASSERT(nwm9buf);
43     return nwm9buf;
44 }
45 
46 
47 /*---------------------------------------------------------------------------*
48   Name:         NWMi_ClearFifoRecvFlag
49 
50   Description:  Notifies the new WM7 that access to FIFO data used by a callback from the new WM7 is complete.
51                 When using a FIFO in a new WM7 callback, wait for this flag to unlock before editing the next callback.
52 
53 
54 
55   Arguments:    None.
56 
57   Returns:      None.
58  *---------------------------------------------------------------------------*/
59 
NWMi_ClearFifoRecvFlag(void)60 void NWMi_ClearFifoRecvFlag(void)
61 {
62     NWMArm7Buf *w7b;
63 
64     if (nwm9buf == NULL) {
65         return;
66     }
67 
68     w7b = nwm9buf->NWM7;
69 
70     // The ARM7 will read the updated value, so invalidate the ARM9 cache
71     DC_InvalidateRange(&w7b->callbackSyncFlag, 1);
72 
73     if (w7b->callbackSyncFlag & NWM_EXCEPTION_CB_MASK)
74     {
75         // Disables the CB exclusion flag
76         w7b->callbackSyncFlag &= ~NWM_EXCEPTION_CB_MASK;
77         // Store cache immediately
78         DC_StoreRange(&w7b->callbackSyncFlag, 1);
79     }
80 }
81 
82 
83 /*---------------------------------------------------------------------------*
84   Name:         NWMi_ReceiveFifo9
85 
86   Description:  Receives a callback from the new WM7 through a FIFO.
87 
88   Arguments:    tag:            Unused
89                 fifo_buf_adr:   Pointer to the callback parameter group
90                 err:            Unused
91 
92   Returns:      None.
93  *---------------------------------------------------------------------------*/
94 
NWMi_ReceiveFifo9(PXIFifoTag tag,u32 fifo_buf_adr,BOOL err)95 void NWMi_ReceiveFifo9(PXIFifoTag tag, u32 fifo_buf_adr, BOOL err)
96 {
97     #pragma unused( tag )
98     NWMCallback *pCallback = (NWMCallback *)fifo_buf_adr;
99     NWMCallbackFunc callback;
100     NWMArm9Buf *w9b = nwm9buf;
101 
102     if (w9b == NULL) {
103         return;
104     }
105 
106     if (err) {
107         NWM_WARNING("NWM9 FIFO receive error. :%d\n", err);
108         return;
109     }
110 
111     if (!fifo_buf_adr) {
112         NWM_WARNING("NWM9 FIFO receive error.(NULL address) :%d\n", err);
113         return;
114     }
115 
116     DC_InvalidateRange(w9b->fifo7to9, NWM_APIFIFO_BUF_SIZE);
117     DC_InvalidateRange(w9b->status, NWM_STATUS_BUF_SIZE);
118     if ((u32)pCallback != (u32)(w9b->fifo7to9))
119     {
120         DC_InvalidateRange(pCallback, NWM_APIFIFO_BUF_SIZE);
121     }
122 
123     NWM_DPRINTF("APIID%04x\n", pCallback->apiid);
124 
125     // Remove the sleep callback if NWM_LoadDevice failed or WM_UnloadDevice succeeded.
126     if( (pCallback->apiid == NWM_APIID_LOAD_DEVICE   && pCallback->retcode != NWM_RETCODE_SUCCESS) ||
127         (pCallback->apiid == NWM_APIID_UNLOAD_DEVICE && pCallback->retcode == NWM_RETCODE_SUCCESS) ||
128          pCallback->apiid == NWM_APIID_INSTALL_FIRMWARE )
129     {
130         NWMi_DeleteSleepCallback();
131     }
132 
133     // Callback processing according to apiid (does nothing if callback not set (NULL))
134     {
135         NWMSendFrameCallback *pSfcb = (NWMSendFrameCallback *)pCallback;
136         NWMRetCode result = NWM_RETCODE_FAILED;
137 
138         if (pCallback->apiid == NWM_APIID_SEND_FRAME)
139         {
140             if (pCallback->retcode != NWM_RETCODE_INDICATION && NULL != pSfcb->callback)
141             {
142                 NWM_DPRINTF("Execute CallbackFunc APIID 0x%04x\n", pCallback->apiid);
143                 (pSfcb->callback)((void *)pCallback);
144             }
145 
146         }
147     }
148 
149     // In the case of several special APIs
150     if (pCallback->apiid == NWM_APIID_SEND_FRAME) {
151         NWMSendFrameCallback *pSfcb = (NWMSendFrameCallback *)pCallback;
152 
153     } else {
154 
155 #ifdef NWM_SUPPORT_HWRESET
156         if (pCallback->apiid == NWM_APIID_UNLOAD_DEVICE
157             || pCallback->apiid == NWM_APIID_INSTALL_FIRMWARE
158             || (pCallback->apiid == NWM_APIID_LOAD_DEVICE
159                 && pCallback->retcode != NWM_RETCODE_SUCCESS)) {
160             // Delete HW reset callback
161             PM_DeletePostExitCallback(&hwResetCbInfo);
162         }
163 #endif
164 
165         // Other APIs
166         callback = w9b->callbackTable[pCallback->apiid];
167 
168         // In case START_SCAN callback, scan buffer cache must be invalidated
169         if (pCallback->apiid == NWM_APIID_START_SCAN) {
170             NWMStartScanCallback *psscb = (NWMStartScanCallback *)pCallback;
171 
172             DC_InvalidateRange(psscb->bssDesc[0], psscb->allBssDescSize);
173         }
174 
175         if (NULL != callback)
176         {
177             NWM_DPRINTF("Execute CallbackFunc APIID 0x%04x\n", pCallback->apiid);
178             (callback) ((void *)pCallback);
179         }
180 
181     }
182 
183     MI_CpuClear8(pCallback, NWM_APIFIFO_BUF_SIZE);
184     DC_StoreRange(pCallback, NWM_APIFIFO_BUF_SIZE);
185     if (w9b) { // NWM might be terminated after callback
186         NWMi_ClearFifoRecvFlag();
187     }
188 
189 }
190 
191 /*---------------------------------------------------------------------------*
192   Name:         NWM_GetState
193 
194   Description:  Checks the internal state of the NWM library.
195                 The purpose for using this is similar to NWMi_CheckState, but its application is largely different so it is provided separately.
196 
197 
198   Arguments:    None.
199 
200   Returns:      u16: Integer that indicates the internal NWM state
201  *---------------------------------------------------------------------------*/
NWM_GetState(void)202 u16 NWM_GetState(void)
203 {
204     NWMStatus*  nwmStatus;
205     NWMArm9Buf* sys = NWMi_GetSystemWork();
206     u16 state = NWM_STATE_NONE;
207 
208     if (sys) {
209         nwmStatus = sys->status;
210         DC_InvalidateRange(nwmStatus, 2);
211         state = nwmStatus->state;
212     }
213 
214     return state;
215 }
216 
217 /*---------------------------------------------------------------------------*
218   Name:         NWMi_CheckState
219 
220   Description:  Checks the internal state of the NWM library.
221                 The WMState parameters indicating the allowed states are specified in a list.
222 
223   Arguments:    paramNum:        Number of virtual arguments
224                 ...:        Virtual argument
225 
226   Returns:      int: Returns the result of the process as an NWM_RETCODE_* value.
227  *---------------------------------------------------------------------------*/
NWMi_CheckState(s32 paramNum,...)228 NWMRetCode NWMi_CheckState(s32 paramNum, ...)
229 {
230     NWMRetCode result;
231     u16     now;
232     u32     temp;
233     va_list vlist;
234     NWMArm9Buf *sys = NWMi_GetSystemWork();
235 
236     SDK_NULL_ASSERT(sys);
237 
238     // Check if initialized
239     result = NWMi_CheckInitialized();
240     NWM_CHECK_RESULT(result);
241 
242     // Gets the current state
243     DC_InvalidateRange(&(sys->status->state), 2);
244     now = sys->status->state;
245 
246     // Match confirmation
247     result = NWM_RETCODE_ILLEGAL_STATE;
248     va_start(vlist, paramNum);
249     for (; paramNum; paramNum--)
250     {
251         temp = va_arg(vlist, u32);
252         if (temp == now)
253         {
254             result = NWM_RETCODE_SUCCESS;
255         }
256     }
257     va_end(vlist);
258 
259     if (result == NWM_RETCODE_ILLEGAL_STATE)
260     {
261         NWM_WARNING("New WM state is \"0x%04x\" now. So can't execute request.\n", now);
262     }
263 
264     return result;
265 }
266 
267 /*---------------------------------------------------------------------------*
268   Name:         NWM_GetAllowedChannel
269 
270   Description:  Gets the IEEE 802.11b/g channel list that can be used with the new wireless functions.
271 
272   Arguments:    None.
273 
274   Returns:      u16: Returns a channel bitmap in the same format as the WM library.
275  *---------------------------------------------------------------------------*/
NWM_GetAllowedChannel(void)276 u16 NWM_GetAllowedChannel(void)
277 {
278     NWMArm9Buf *sys = NWMi_GetSystemWork();
279 
280     return sys->status->allowedChannel;
281 }
282 
283 /*---------------------------------------------------------------------------*
284   Name:         NWM_CalcLinkLevel
285 
286   Description:  Calculates the link level from the threshold value defined in nwm_common_private.h.
287 
288   Arguments:    s16: The RSSI value sent with a notification from the Atheros driver
289 
290   Returns:      u16: The same link level as the WM library
291  *---------------------------------------------------------------------------*/
NWM_CalcLinkLevel(s16 rssi)292 u16 NWM_CalcLinkLevel(s16 rssi)
293 {
294 
295 /* [TODO] Does this need to be switched depending on the operating mode? If this is necessary, the conditional statement must be revised. */
296 
297     if(1) /* Infra Structure Mode */
298     {
299         if(rssi < NWM_RSSI_INFRA_LINK_LEVEL_1)
300         {
301             return WM_LINK_LEVEL_0;
302         }
303         if(rssi < NWM_RSSI_INFRA_LINK_LEVEL_2)
304         {
305             return WM_LINK_LEVEL_1;
306         }
307         if(rssi < NWM_RSSI_INFRA_LINK_LEVEL_3)
308         {
309             return WM_LINK_LEVEL_2;
310         }
311 
312         return WM_LINK_LEVEL_3;
313     }
314     else if(0) /*Ad Hoc Mode*/
315     {
316         if(rssi < NWM_RSSI_ADHOC_LINK_LEVEL_1)
317         {
318             return WM_LINK_LEVEL_0;
319         }
320         if(rssi < NWM_RSSI_ADHOC_LINK_LEVEL_2)
321         {
322             return WM_LINK_LEVEL_1;
323         }
324         if(rssi < NWM_RSSI_ADHOC_LINK_LEVEL_3)
325         {
326             return WM_LINK_LEVEL_2;
327         }
328         return WM_LINK_LEVEL_3;
329     }
330 
331 }
332 
333 /*---------------------------------------------------------------------------*
334   Name:         NWM_GetDispersionScanPeriod
335 
336   Description:  Gets the time limit that should be set on searching for an AP or DS parent device as an STA.
337 
338   Arguments:    u16 scanType: The scan type, either NWM_SCANTYPE_PASSIVE or NWM_SCANTYPE_ACTIVE.
339 
340   Returns:      u16:    Search limit time that should be set (ms)
341  *---------------------------------------------------------------------------*/
NWM_GetDispersionScanPeriod(u16 scanType)342 u16 NWM_GetDispersionScanPeriod(u16 scanType)
343 {
344     u8      mac[6];
345     u16     ret;
346     s32     i;
347 
348     OS_GetMacAddress(mac);
349     for (i = 0, ret = 0; i < 6; i++)
350     {
351         ret += mac[i];
352     }
353     ret += OS_GetVBlankCount();
354     ret *= 13;
355 
356     if( scanType == NWM_SCANTYPE_ACTIVE )
357     {
358         ret = (u16)(NWM_DEFAULT_ACTIVE_SCAN_PERIOD + (ret % 10));
359     }
360     else /* An unknown scan type is treated in the same way as a passive scan */
361     {
362         ret = (u16)(NWM_DEFAULT_PASSIVE_SCAN_PERIOD + (ret % 10));
363     }
364     return ret;
365 }
366 
367 /*---------------------------------------------------------------------------*
368   Name:         NWMi_RegisterSleepCallback
369 
370   Description:  Registers the callback function that will be run when entering Sleep Mode.
371 
372   Arguments:    None.
373 
374   Returns:      None.
375  *---------------------------------------------------------------------------*/
NWMi_RegisterSleepCallback(void)376 void NWMi_RegisterSleepCallback(void)
377 {
378     PM_SetSleepCallbackInfo(&sleepCbInfo, NwmSleepCallback, NULL);
379     PMi_InsertPreSleepCallbackEx(&sleepCbInfo, PM_CALLBACK_PRIORITY_NWM );
380 }
381 
382 /*---------------------------------------------------------------------------*
383   Name:         NWMi_DeleteSleepCallback
384 
385   Description:  Deletes the callback function that is run when entering Sleep Mode.
386 
387   Arguments:    None.
388 
389   Returns:      None.
390  *---------------------------------------------------------------------------*/
NWMi_DeleteSleepCallback(void)391 void NWMi_DeleteSleepCallback(void)
392 {
393     PM_DeletePreSleepCallback( &sleepCbInfo );
394 }
395 
396 /*---------------------------------------------------------------------------*
397   Name:         NwmSleepCallback
398 
399   Description:  Prevents the program from entering Sleep Mode during wireless communications.
400 
401   Arguments:    None.
402 
403   Returns:      None.
404  *---------------------------------------------------------------------------*/
NwmSleepCallback(void *)405 static void NwmSleepCallback(void *)
406 {
407     /* ---------------------------------------------- *
408      * As described in section 6.5 of the Programming Guidelines, it is prohibited to run OS_GoSleepMode() during wireless communications
409      *
410      *
411      * ---------------------------------------------- */
412     OS_Panic("Could not sleep during wireless communications.");
413 }
414 
415 /*---------------------------------------------------------------------------*
416     End of file
417  *---------------------------------------------------------------------------*/
418