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