1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - NWM - libraries
3   File:     nwm_system.c
4 
5   Copyright 2007-2009 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:: 2009-06-19#$
14   $Rev: 10786 $
15   $Author: okajima_manabu $
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 
52                 When using a FIFO in a new WM7 callback, wait for this flag to unlock before editing the next callback.
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         // Clears 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     // When 'apiid' is an unexpected value (NWM_APIID_ASYNC_KIND_MAX or more)
117     if(pCallback->apiid >= NWM_APIID_ASYNC_KIND_MAX)
118     {
119         NWM_WARNING("Receive Unknown APIID(%d)\n",pCallback->apiid);
120         return;
121     }
122 
123     DC_InvalidateRange(w9b->fifo7to9, NWM_APIFIFO_BUF_SIZE);
124     DC_InvalidateRange(w9b->status, NWM_STATUS_BUF_SIZE);
125     if ((u32)pCallback != (u32)(w9b->fifo7to9))
126     {
127         DC_InvalidateRange(pCallback, NWM_APIFIFO_BUF_SIZE);
128     }
129 
130     NWM_DPRINTF("APIID%04x\n", pCallback->apiid);
131 
132     // Remove the sleep callback if NWM_LoadDevice failed or WM_UnloadDevice succeeded.
133     if( (pCallback->apiid == NWM_APIID_LOAD_DEVICE   && pCallback->retcode != NWM_RETCODE_SUCCESS) ||
134         (pCallback->apiid == NWM_APIID_UNLOAD_DEVICE && pCallback->retcode == NWM_RETCODE_SUCCESS) ||
135          pCallback->apiid == NWM_APIID_INSTALL_FIRMWARE )
136     {
137         NWMi_DeleteSleepCallback();
138     }
139 
140     // Callback processing according to apiid (does nothing if callback not set (NULL))
141     {
142         NWMSendFrameCallback *pSfcb = (NWMSendFrameCallback *)pCallback;
143         NWMRetCode result = NWM_RETCODE_FAILED;
144 
145         if (pCallback->apiid == NWM_APIID_SEND_FRAME)
146         {
147             if (pCallback->retcode != NWM_RETCODE_INDICATION && NULL != pSfcb->callback)
148             {
149                 NWM_DPRINTF("Execute CallbackFunc APIID 0x%04x\n", pCallback->apiid);
150                 (pSfcb->callback)((void *)pCallback);
151             }
152 
153         }
154     }
155 
156     // In the case of several special APIs
157     if (pCallback->apiid == NWM_APIID_SEND_FRAME) {
158         NWMSendFrameCallback *pSfcb = (NWMSendFrameCallback *)pCallback;
159 
160     } else {
161 
162 #ifdef NWM_SUPPORT_HWRESET
163         if (pCallback->apiid == NWM_APIID_UNLOAD_DEVICE
164             || pCallback->apiid == NWM_APIID_INSTALL_FIRMWARE
165             || (pCallback->apiid == NWM_APIID_LOAD_DEVICE
166                 && pCallback->retcode != NWM_RETCODE_SUCCESS)) {
167             // Delete HW reset callback
168             PM_DeletePostExitCallback(&hwResetCbInfo);
169         }
170 #endif
171 
172         // Other APIs
173         callback = w9b->callbackTable[pCallback->apiid];
174 
175         // In case START_SCAN callback, scan buffer cache must be invalidated.
176         if (pCallback->apiid == NWM_APIID_START_SCAN) {
177             NWMStartScanCallback *psscb = (NWMStartScanCallback *)pCallback;
178 
179             DC_InvalidateRange(psscb->bssDesc[0], psscb->allBssDescSize);
180         }
181 
182         if (NULL != callback)
183         {
184             NWM_DPRINTF("Execute CallbackFunc APIID 0x%04x\n", pCallback->apiid);
185             (callback) ((void *)pCallback);
186         }
187 
188     }
189 
190     MI_CpuClear8(pCallback, NWM_APIFIFO_BUF_SIZE);
191     DC_StoreRange(pCallback, NWM_APIFIFO_BUF_SIZE);
192     if (w9b) { // NWM might be terminated after callback
193         NWMi_ClearFifoRecvFlag();
194     }
195 
196 }
197 
198 /*---------------------------------------------------------------------------*
199   Name:         NWM_GetState
200 
201   Description:  Checks the internal state of the NWM library.
202                 The purpose for using this is similar to NWMi_CheckState, but its application is largely different so it is provided separately.
203 
204 
205   Arguments:    None.
206 
207   Returns:      u16: Integer that indicates the internal NWM state
208  *---------------------------------------------------------------------------*/
NWM_GetState(void)209 u16 NWM_GetState(void)
210 {
211     NWMStatus*  nwmStatus;
212     NWMArm9Buf* sys = NWMi_GetSystemWork();
213     u16 state = NWM_STATE_NONE;
214 
215     if (sys) {
216         nwmStatus = sys->status;
217         DC_InvalidateRange(nwmStatus, 2);
218         state = nwmStatus->state;
219     }
220 
221     return state;
222 }
223 
224 /*---------------------------------------------------------------------------*
225   Name:         NWMi_CheckState
226 
227   Description:  Checks the internal state of the NWM library.
228                 Specifies the WMState type parameters showing the permitted state by enumerating them.
229 
230   Arguments:    paramNum: Number of virtual arguments
231                 ...: Virtual argument
232 
233   Returns:      int: Returns the result of the process as an NWM_RETCODE_* value.
234  *---------------------------------------------------------------------------*/
NWMi_CheckState(s32 paramNum,...)235 NWMRetCode NWMi_CheckState(s32 paramNum, ...)
236 {
237     NWMRetCode result;
238     u16     now;
239     u32     temp;
240     va_list vlist;
241     NWMArm9Buf *sys = NWMi_GetSystemWork();
242 
243     SDK_NULL_ASSERT(sys);
244 
245     // Check if initialized
246     result = NWMi_CheckInitialized();
247     NWM_CHECK_RESULT(result);
248 
249     // Gets the current state
250     DC_InvalidateRange(&(sys->status->state), 2);
251     now = sys->status->state;
252 
253     // Match confirmation
254     result = NWM_RETCODE_ILLEGAL_STATE;
255     va_start(vlist, paramNum);
256     for (; paramNum; paramNum--)
257     {
258         temp = va_arg(vlist, u32);
259         if (temp == now)
260         {
261             result = NWM_RETCODE_SUCCESS;
262         }
263     }
264     va_end(vlist);
265 
266     if (result == NWM_RETCODE_ILLEGAL_STATE)
267     {
268         NWM_WARNING("New WM state is \"0x%04x\" now. So can't execute request.\n", now);
269     }
270 
271     return result;
272 }
273 
274 /*---------------------------------------------------------------------------*
275   Name:         NWM_GetAllowedChannel
276 
277   Description:  Gets the IEEE 802.11b/g channel list that can be used with the new wireless functions.
278 
279   Arguments:    None.
280 
281   Returns:      u16: Returns a channel bitmap in the same format as the WM library.
282  *---------------------------------------------------------------------------*/
NWM_GetAllowedChannel(void)283 u16 NWM_GetAllowedChannel(void)
284 {
285     NWMArm9Buf *sys = NWMi_GetSystemWork();
286 
287     return sys->status->allowedChannel;
288 }
289 
290 /*---------------------------------------------------------------------------*
291   Name:         NWM_CalcLinkLevel
292 
293   Description:  Calculates the link level from the threshold value defined in nwm_common_private.h.
294 
295   Arguments:    s16: RSSI value sent with a notification from the Atheros driver
296 
297   Returns:      u16: The same link level as the WM library.
298  *---------------------------------------------------------------------------*/
NWM_CalcLinkLevel(s16 rssi)299 u16 NWM_CalcLinkLevel(s16 rssi)
300 {
301 
302 /* [TODO] Does this need to be switched depending on the operating mode? If this is necessary, the conditional statement must be revised. */
303 
304     if(1) /* Infra Structure Mode */
305     {
306         if(rssi < NWM_RSSI_INFRA_LINK_LEVEL_1)
307         {
308             return WM_LINK_LEVEL_0;
309         }
310         if(rssi < NWM_RSSI_INFRA_LINK_LEVEL_2)
311         {
312             return WM_LINK_LEVEL_1;
313         }
314         if(rssi < NWM_RSSI_INFRA_LINK_LEVEL_3)
315         {
316             return WM_LINK_LEVEL_2;
317         }
318 
319         return WM_LINK_LEVEL_3;
320     }
321     else if(0) /*Ad Hoc Mode*/
322     {
323         if(rssi < NWM_RSSI_ADHOC_LINK_LEVEL_1)
324         {
325             return WM_LINK_LEVEL_0;
326         }
327         if(rssi < NWM_RSSI_ADHOC_LINK_LEVEL_2)
328         {
329             return WM_LINK_LEVEL_1;
330         }
331         if(rssi < NWM_RSSI_ADHOC_LINK_LEVEL_3)
332         {
333             return WM_LINK_LEVEL_2;
334         }
335         return WM_LINK_LEVEL_3;
336     }
337 
338 }
339 
340 /*---------------------------------------------------------------------------*
341   Name:         NWM_GetDispersionScanPeriod
342 
343   Description:  Gets the time limit that should be set on searching for an AP or DS parent device as an STA.
344 
345   Arguments:    u16 scanType: Scan type, either NWM_SCANTYPE_PASSIVE or NWM_SCANTYPE_ACTIVE
346 
347   Returns:      u16: Search limit time that should be set (ms).
348  *---------------------------------------------------------------------------*/
NWM_GetDispersionScanPeriod(u16 scanType)349 u16 NWM_GetDispersionScanPeriod(u16 scanType)
350 {
351     u8      mac[6];
352     u16     ret;
353     s32     i;
354 
355     OS_GetMacAddress(mac);
356     for (i = 0, ret = 0; i < 6; i++)
357     {
358         ret += mac[i];
359     }
360     ret += OS_GetVBlankCount();
361     ret *= 13;
362 
363     if( scanType == NWM_SCANTYPE_ACTIVE )
364     {
365         ret = (u16)(NWM_DEFAULT_ACTIVE_SCAN_PERIOD + (ret % 10));
366     }
367     else /* An unknown scan type is treated in the same way as a passive scan */
368     {
369         ret = (u16)(NWM_DEFAULT_PASSIVE_SCAN_PERIOD + (ret % 10));
370     }
371     return ret;
372 }
373 
374 /*---------------------------------------------------------------------------*
375   Name:         NWMi_RegisterSleepCallback
376 
377   Description:  Registers the callback function that will be run when shifting to Sleep Mode.
378 
379   Arguments:    None.
380 
381   Returns:      None.
382  *---------------------------------------------------------------------------*/
NWMi_RegisterSleepCallback(void)383 void NWMi_RegisterSleepCallback(void)
384 {
385     PM_SetSleepCallbackInfo(&sleepCbInfo, NwmSleepCallback, NULL);
386     PMi_InsertPreSleepCallbackEx(&sleepCbInfo, PM_CALLBACK_PRIORITY_NWM );
387 }
388 
389 /*---------------------------------------------------------------------------*
390   Name:         NWMi_DeleteSleepCallback
391 
392   Description:  Deletes the callback function that is run when shifting to Sleep Mode.
393 
394   Arguments:    None.
395 
396   Returns:      None.
397  *---------------------------------------------------------------------------*/
NWMi_DeleteSleepCallback(void)398 void NWMi_DeleteSleepCallback(void)
399 {
400     PM_DeletePreSleepCallback( &sleepCbInfo );
401 }
402 
403 /*---------------------------------------------------------------------------*
404   Name:         NwmSleepCallback
405 
406   Description:  Prevents the program from entering Sleep Mode during wireless communications.
407 
408   Arguments:    None.
409 
410   Returns:      None.
411  *---------------------------------------------------------------------------*/
NwmSleepCallback(void *)412 static void NwmSleepCallback(void *)
413 {
414     /* ---------------------------------------------- *
415      * As described in the Programming Guidelines, it is prohibited to run the OS_GoSleepMode function during wireless communications. *
416      *                                                *
417      *                                                *
418      * ---------------------------------------------- */
419     OS_TPanic("Could not sleep during wireless communications.");
420 }
421 
422 /*---------------------------------------------------------------------------*
423     End of file
424  *---------------------------------------------------------------------------*/
425