1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - WM - libraries
3 File: wm_system.c
4
5 Copyright 2003-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 <nitro/wm.h>
19 #include "wm_arm9_private.h"
20
21 #ifdef SDK_TWL /* Strengthens checks during TWL initialization */
22 #include "wm_common.h"
23 #endif //SDK_TWL
24
25 /*---------------------------------------------------------------------------*
26 Constant Definitions
27 *---------------------------------------------------------------------------*/
28 #define WM_BUF_MSG_NUM 10
29
30
31 /*---------------------------------------------------------------------------*
32 Internal Variable Definitions
33 *---------------------------------------------------------------------------*/
34 static u16 wmInitialized = 0; // WM initialization flag
35 static WMArm9Buf *wm9buf;
36 static u32 fifoBuf[WM_BUF_MSG_NUM][WM_FIFO_BUF_SIZE / sizeof(u32)] ATTRIBUTE_ALIGN(32);
37 static OSMessageQueue bufMsgQ; // Request queue for WM7
38 static OSMessage bufMsg[WM_BUF_MSG_NUM]; // Request queue buffer for WM7
39 static PMSleepCallbackInfo sleepCbInfo; //Sleep callback information to register with the PM library
40
41
42 /*---------------------------------------------------------------------------*
43 Internal Function Definitions
44 *---------------------------------------------------------------------------*/
45 static void WmReceiveFifo(PXIFifoTag tag, u32 fifo_buf_adr, BOOL err);
46 static void WmClearFifoRecvFlag(void);
47 static WMErrCode WmInitCore(void *wmSysBuf, u16 dmaNo, u32 bufSize);
48 static u32 *WmGetCommandBuffer4Arm7(void);
49 static void WmSleepCallback(void *);
50
51 /*---------------------------------------------------------------------------*
52 Name: WM_Init
53
54 Description: Performs the initialization process for the WM library.
55 Synchronous function that only initializes ARM9.
56
57 Arguments: wmSysBuf: Pointer to the buffer allocated by the caller.
58 The required buffer size is only WM_SYSTEM_BUF_SIZE.
59 dmaNo: DMA number used by WM
60
61 Returns: WMErrCode: Returns the processing result.
62 *---------------------------------------------------------------------------*/
WM_Init(void * wmSysBuf,u16 dmaNo)63 WMErrCode WM_Init(void *wmSysBuf, u16 dmaNo)
64 {
65 WMErrCode result;
66
67 result = WmInitCore(wmSysBuf, dmaNo, WM_SYSTEM_BUF_SIZE);
68 if (result != WM_ERRCODE_SUCCESS)
69 {
70 return result;
71 }
72 wm9buf->scanOnlyFlag = FALSE;
73 return result;
74 }
75
76 /*---------------------------------------------------------------------------*
77 Name: WMi_InitForScan
78
79 Description: Performs initialization processing for WM library when using only scan.
80 Synchronous function that only initializes ARM9.
81
82 Arguments: wmSysBuf: Pointer to the buffer allocated by the caller.
83 The required buffer size is only WM_SYSTEM_BUF_SIZE_FOR_SCAN.
84 dmaNo: DMA number used by WM
85
86 Returns: WMErrCode: Returns the processing result.
87 *---------------------------------------------------------------------------*/
88 WMErrCode WMi_InitForScan(void *wmSysBuf, u16 dmaNo);
WMi_InitForScan(void * wmSysBuf,u16 dmaNo)89 WMErrCode WMi_InitForScan(void *wmSysBuf, u16 dmaNo)
90 {
91 #define WM_STATUS_BUF_SIZE_FOR_SCAN 768
92 #define WM_ARM9WM_BUF_SIZE_FOR_SCAN 320
93 #define WM_SYSTEM_BUF_SIZE_FOR_SCAN (WM_ARM9WM_BUF_SIZE_FOR_SCAN + WM_ARM7WM_BUF_SIZE + WM_STATUS_BUF_SIZE_FOR_SCAN + WM_FIFO_BUF_SIZE + WM_FIFO_BUF_SIZE)
94
95 WMErrCode result;
96 result = WmInitCore(wmSysBuf, dmaNo, WM_SYSTEM_BUF_SIZE_FOR_SCAN);
97 if (result != WM_ERRCODE_SUCCESS)
98 {
99 return result;
100 }
101 wm9buf = (WMArm9Buf *)wmSysBuf;
102 wm9buf->WM7 = (WMArm7Buf *)((u32)wm9buf + WM_ARM9WM_BUF_SIZE_FOR_SCAN);
103 wm9buf->status = (WMStatus *)((u32)(wm9buf->WM7) + WM_ARM7WM_BUF_SIZE);
104 wm9buf->fifo9to7 = (u32 *)((u32)(wm9buf->status) + WM_STATUS_BUF_SIZE_FOR_SCAN);
105 wm9buf->fifo7to9 = (u32 *)((u32)(wm9buf->fifo9to7) + WM_FIFO_BUF_SIZE);
106 wm9buf->dmaNo = dmaNo;
107 wm9buf->scanOnlyFlag = TRUE;
108
109 return result;
110 }
111
112 /*---------------------------------------------------------------------------*
113 Name: WmInitCore
114
115 Description: Library internal use function that performs WM library initialization process.
116 Synchronous function that only initializes ARM9.
117
118 Arguments: wmSysBuf: Pointer to the buffer allocated by the caller
119 dmaNo: DMA number used by WM
120 bufSize: Buffer size allocated to WM library
121
122 Returns: WMErrCode: Returns the processing result.
123 *---------------------------------------------------------------------------*/
WmInitCore(void * wmSysBuf,u16 dmaNo,u32 bufSize)124 static WMErrCode WmInitCore(void *wmSysBuf, u16 dmaNo, u32 bufSize)
125 {
126 OSIntrMode e;
127
128 // Checks if the structure size exceeds the expected value
129 SDK_COMPILER_ASSERT(sizeof(WMArm9Buf) <= WM_ARM9WM_BUF_SIZE);
130 SDK_COMPILER_ASSERT(sizeof(WMArm7Buf) <= WM_ARM7WM_BUF_SIZE);
131 SDK_COMPILER_ASSERT(sizeof(WMStatus) <= WM_STATUS_BUF_SIZE);
132
133 e = OS_DisableInterrupts();
134
135 #ifdef SDK_TWL
136 if( OS_IsRunOnTwl() )
137 {
138 /* Check that the NWM library has not been initialized */
139 if (NWM_CheckInitialized() != NWM_RETCODE_ILLEGAL_STATE)
140 {
141 WM_WARNING("NWM has already been initialized.\n");
142 (void)OS_RestoreInterrupts(e);
143 return WM_ERRCODE_ILLEGAL_STATE;
144 }
145 }
146 #endif
147
148 /* Confirms that the WM library initialization is complete. */
149 if (wmInitialized)
150 {
151 WM_WARNING("WM has already been initialized.\n");
152 (void)OS_RestoreInterrupts(e);
153 return WM_ERRCODE_ILLEGAL_STATE; // Initialization complete
154 }
155
156 // Check parameters
157 if (wmSysBuf == NULL)
158 {
159 WM_WARNING("Parameter \"wmSysBuf\" must not be NULL.\n");
160 (void)OS_RestoreInterrupts(e);
161 return WM_ERRCODE_INVALID_PARAM;
162 }
163 // Because of WM PXI usage, wmSysBuf cannot be placed at an address of 0x04000000 or higher
164 #ifdef SDK_TWL
165 if( OS_IsOnVram(wmSysBuf) || ( OS_IsRunOnTwl() && OS_IsOnExtendedMainMemory(wmSysBuf) ) )
166 #else
167 if( OS_IsOnVram(wmSysBuf) )
168 #endif
169 {
170 WM_WARNING("Parameter \"wmSysBuf\" must be alocated less than 0x04000000.\n");
171 (void)OS_RestoreInterrupts(e);
172 return WM_ERRCODE_INVALID_PARAM;
173 }
174
175 if (dmaNo > MI_DMA_MAX_NUM)
176 {
177 WM_WARNING("Parameter \"dmaNo\" is over %d.\n", MI_DMA_MAX_NUM);
178 (void)OS_RestoreInterrupts(e);
179 return WM_ERRCODE_INVALID_PARAM;
180 }
181 if ((u32)wmSysBuf & 0x01f)
182 {
183 WM_WARNING("Parameter \"wmSysBuf\" must be 32-byte aligned.\n");
184 (void)OS_RestoreInterrupts(e);
185 return WM_ERRCODE_INVALID_PARAM;
186 }
187
188 // Confirms whether the WM library has started on the ARM7
189 PXI_Init();
190 if (!PXI_IsCallbackReady(PXI_FIFO_TAG_WM, PXI_PROC_ARM7))
191 {
192 WM_WARNING("WM library on ARM7 side is not ready yet.\n");
193 (void)OS_RestoreInterrupts(e);
194 return WM_ERRCODE_WM_DISABLE;
195 }
196
197 /* If there is excess data remaining in the cache, a write-back could occur unexpectedly and interfere with state management on the ARM7.
198
199 As a countermeasure, delete the cache of all work buffers at this point. */
200 DC_InvalidateRange(wmSysBuf, bufSize);
201 // Initialization for various types of buffers
202 MI_DmaClear32(dmaNo, wmSysBuf, bufSize);
203 wm9buf = (WMArm9Buf *)wmSysBuf;
204 wm9buf->WM7 = (WMArm7Buf *)((u32)wm9buf + WM_ARM9WM_BUF_SIZE);
205 wm9buf->status = (WMStatus *)((u32)(wm9buf->WM7) + WM_ARM7WM_BUF_SIZE);
206 wm9buf->fifo9to7 = (u32 *)((u32)(wm9buf->status) + WM_STATUS_BUF_SIZE);
207 wm9buf->fifo7to9 = (u32 *)((u32)(wm9buf->fifo9to7) + WM_FIFO_BUF_SIZE);
208
209 // Clears the FIFO buffer writable flag
210 WmClearFifoRecvFlag();
211
212 // Initializes the various types of variables
213 wm9buf->dmaNo = dmaNo;
214 wm9buf->connectedAidBitmap = 0x0000;
215 wm9buf->myAid = 0;
216
217 // Initializes the callback table for each port
218 {
219 s32 i;
220
221 for (i = 0; i < WM_NUM_OF_PORT; i++)
222 {
223 wm9buf->portCallbackTable[i] = NULL;
224 wm9buf->portCallbackArgument[i] = NULL;
225 }
226 }
227
228 // Initializes the queue for entry registration
229 {
230 s32 i;
231
232 OS_InitMessageQueue(&bufMsgQ, bufMsg, WM_BUF_MSG_NUM);
233 for (i = 0; i < WM_BUF_MSG_NUM; i++)
234 {
235 // Clears the ring buffer to the usable state
236 *((u16 *)(fifoBuf[i])) = WM_API_REQUEST_ACCEPTED;
237 DC_StoreRange(fifoBuf[i], 2);
238 (void)OS_SendMessage(&bufMsgQ, fifoBuf[i], OS_MESSAGE_BLOCK);
239 }
240 }
241
242 // Sets FIFO receive function
243 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_WM, WmReceiveFifo);
244
245 wmInitialized = 1;
246 (void)OS_RestoreInterrupts(e);
247 return WM_ERRCODE_SUCCESS;
248 }
249
250 /*---------------------------------------------------------------------------*
251 Name: WM_Finish
252
253 Description: Performs termination processing for WM library. Synchronous function.
254 Restores the state before WM_Init function was called.
255
256 Arguments: None.
257
258 Returns: WMErrCode: Returns the processing result.
259 *---------------------------------------------------------------------------*/
WM_Finish(void)260 WMErrCode WM_Finish(void)
261 {
262 OSIntrMode e;
263 WMErrCode result;
264
265 e = OS_DisableInterrupts();
266 // Cannot execute if initialization is incomplete
267 result = WMi_CheckInitialized();
268 if (result != WM_ERRCODE_SUCCESS)
269 {
270 (void)OS_RestoreInterrupts(e);
271 return WM_ERRCODE_ILLEGAL_STATE;
272 }
273
274 // Cannot execute if the state is not READY
275 result = WMi_CheckState(WM_STATE_READY);
276 WM_CHECK_RESULT(result);
277
278 // Close WM library
279 WmClearFifoRecvFlag();
280 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_WM, NULL);
281 wm9buf = 0;
282
283 wmInitialized = 0;
284 (void)OS_RestoreInterrupts(e);
285 return WM_ERRCODE_SUCCESS;
286 }
287
288 /*---------------------------------------------------------------------------*
289 Name: WMi_SetCallbackTable
290
291 Description: Registers the callback function for each asynchronous function.
292
293 Arguments: id: Asynchronous function's API ID
294 callback: Callback function to be registered
295
296 Returns: None.
297 *---------------------------------------------------------------------------*/
WMi_SetCallbackTable(WMApiid id,WMCallbackFunc callback)298 void WMi_SetCallbackTable(WMApiid id, WMCallbackFunc callback)
299 {
300 SDK_NULL_ASSERT(wm9buf);
301
302 wm9buf->CallbackTable[id] = callback;
303 }
304
305 /*---------------------------------------------------------------------------*
306 Name: WmGetCommandBuffer4Arm7
307
308 Description: Reserves from the pool a buffer for commands directed to ARM7.
309
310 Arguments: None.
311
312 Returns: If it can be reserved, it is that value; otherwise, NULL.
313 *---------------------------------------------------------------------------*/
WmGetCommandBuffer4Arm7(void)314 u32 *WmGetCommandBuffer4Arm7(void)
315 {
316 u32 *tmpAddr;
317
318 if (FALSE == OS_ReceiveMessage(&bufMsgQ, (OSMessage *)&tmpAddr, OS_MESSAGE_NOBLOCK))
319 {
320 return NULL;
321 }
322
323 // Check if the ring buffer is available (queue is not full)
324 DC_InvalidateRange(tmpAddr, 2);
325 if ((*((u16 *)tmpAddr) & WM_API_REQUEST_ACCEPTED) == 0)
326 {
327 // Reserve again at the beginning of the queue (because this should be first to come available)
328 (void)OS_JamMessage(&bufMsgQ, tmpAddr, OS_MESSAGE_BLOCK);
329 // End with an error
330 return NULL;
331 }
332
333 return tmpAddr;
334 }
335
336 /*---------------------------------------------------------------------------*
337 Name: WMi_SendCommand
338
339 Description: Transmits a request to the ARM7 via the FIFO.
340 For commands accompanied by some number of u32-type parameters, specify the parameters by enumerating them.
341
342
343 Arguments: id: API ID that corresponds to the request
344 paramNum: Number of virtual arguments
345 ...: Virtual argument
346
347 Returns: int: Returns a WM_ERRCODE_* type processing result.
348 *---------------------------------------------------------------------------*/
WMi_SendCommand(WMApiid id,u16 paramNum,...)349 WMErrCode WMi_SendCommand(WMApiid id, u16 paramNum, ...)
350 {
351 va_list vlist;
352 s32 i;
353 int result;
354 u32 *tmpAddr;
355
356 SDK_NULL_ASSERT(wm9buf);
357
358 // Reserves a buffer for command sending
359 tmpAddr = WmGetCommandBuffer4Arm7();
360 if (tmpAddr == NULL)
361 {
362 return WM_ERRCODE_FIFO_ERROR;
363 }
364
365 // API ID
366 *(u16 *)tmpAddr = (u16)id;
367
368 // Adds the specified number of arguments
369 va_start(vlist, paramNum);
370 for (i = 0; i < paramNum; i++)
371 {
372 tmpAddr[i + 1] = va_arg(vlist, u32);
373 }
374 va_end(vlist);
375
376 DC_StoreRange(tmpAddr, WM_FIFO_BUF_SIZE);
377
378 // Notification with FIFO
379 result = PXI_SendWordByFifo(PXI_FIFO_TAG_WM, (u32)tmpAddr, FALSE);
380
381 (void)OS_SendMessage(&bufMsgQ, tmpAddr, OS_MESSAGE_BLOCK);
382
383 if (result < 0)
384 {
385 WM_WARNING("Failed to send command through FIFO.\n");
386 return WM_ERRCODE_FIFO_ERROR;
387 }
388
389 return WM_ERRCODE_OPERATING;
390 }
391
392 /*---------------------------------------------------------------------------*
393 Name: WMi_SendCommandDirect
394
395 Description: Transmits a request to the ARM7 via the FIFO.
396 Directly specifies the command sent to the ARM7.
397
398 Arguments: data: Command sent to the ARM7
399 length: Size of the command sent to the ARM7
400
401 Returns: int: Returns a WM_ERRCODE_* type processing result.
402 *---------------------------------------------------------------------------*/
WMi_SendCommandDirect(void * data,u32 length)403 WMErrCode WMi_SendCommandDirect(void *data, u32 length)
404 {
405 int result;
406 u32 *tmpAddr;
407
408 SDK_NULL_ASSERT(wm9buf);
409 SDK_ASSERT(length <= WM_FIFO_BUF_SIZE);
410
411 // Reserves a buffer for command sending
412 tmpAddr = WmGetCommandBuffer4Arm7();
413 if (tmpAddr == NULL)
414 {
415 return WM_ERRCODE_FIFO_ERROR;
416 }
417
418 // Copies to a buffer specifically for commands sent to the ARM7
419 MI_CpuCopy8(data, tmpAddr, length);
420
421 DC_StoreRange(tmpAddr, length);
422
423 // Notification with FIFO
424 result = PXI_SendWordByFifo(PXI_FIFO_TAG_WM, (u32)tmpAddr, FALSE);
425
426 (void)OS_SendMessage(&bufMsgQ, tmpAddr, OS_MESSAGE_BLOCK);
427
428 if (result < 0)
429 {
430 WM_WARNING("Failed to send command through FIFO.\n");
431 return WM_ERRCODE_FIFO_ERROR;
432 }
433
434 return WM_ERRCODE_OPERATING;
435 }
436
437 /*---------------------------------------------------------------------------*
438 Name: WMi_GetSystemWork
439
440 Description: Gets the pointer to the front of the buffer used internally by the WM library.
441
442 Arguments: None.
443
444 Returns: WMArm9Buf*: Returns a pointer to the internal work buffer.
445 *---------------------------------------------------------------------------*/
WMi_GetSystemWork(void)446 WMArm9Buf *WMi_GetSystemWork(void)
447 {
448 // SDK_NULL_ASSERT(wm9buf);
449 return wm9buf;
450 }
451
452 /*---------------------------------------------------------------------------*
453 Name: WMi_CheckInitialized
454
455 Description: Confirms that the WM library initialization is complete.
456
457 Arguments: None.
458
459 Returns: int: Returns a WM_ERRCODE_* type processing result.
460 *---------------------------------------------------------------------------*/
WMi_CheckInitialized(void)461 WMErrCode WMi_CheckInitialized(void)
462 {
463 // Check if initialized
464 if (!wmInitialized)
465 {
466 return WM_ERRCODE_ILLEGAL_STATE;
467 }
468 return WM_ERRCODE_SUCCESS;
469 }
470
471 /*---------------------------------------------------------------------------*
472 Name: WMi_CheckIdle
473
474 Description: Confirms the internal state of the WM library, and confirms that the wireless hardware has already started.
475
476
477 Arguments: None.
478
479 Returns: int: Returns a WM_ERRCODE_* type processing result.
480 *---------------------------------------------------------------------------*/
WMi_CheckIdle(void)481 WMErrCode WMi_CheckIdle(void)
482 {
483 WMErrCode result;
484
485 // Check if initialized
486 result = WMi_CheckInitialized();
487 WM_CHECK_RESULT(result);
488
489 // Confirms the current state
490 DC_InvalidateRange(&(wm9buf->status->state), 2);
491 if ((wm9buf->status->state == WM_STATE_READY) || (wm9buf->status->state == WM_STATE_STOP))
492 {
493 WM_WARNING("WM state is \"%d\" now. So can't execute request.\n", wm9buf->status->state);
494 return WM_ERRCODE_ILLEGAL_STATE;
495 }
496
497 return WM_ERRCODE_SUCCESS;
498 }
499
500 /*---------------------------------------------------------------------------*
501 Name: WMi_CheckStateEx
502
503 Description: Confirms the internal state of the WM library.
504 Specifies the WMState type parameters showing the permitted state by enumerating them.
505
506 Arguments: paramNum: Number of virtual arguments
507 ...: Virtual argument
508
509 Returns: int: Returns a WM_ERRCODE_* type processing result.
510 *---------------------------------------------------------------------------*/
WMi_CheckStateEx(s32 paramNum,...)511 WMErrCode WMi_CheckStateEx(s32 paramNum, ...)
512 {
513 WMErrCode result;
514 u16 now;
515 u32 temp;
516 va_list vlist;
517
518 // Check if initialized
519 result = WMi_CheckInitialized();
520 WM_CHECK_RESULT(result);
521
522 // Gets the current state
523 DC_InvalidateRange(&(wm9buf->status->state), 2);
524 now = wm9buf->status->state;
525
526 // Match confirmation
527 result = WM_ERRCODE_ILLEGAL_STATE;
528 va_start(vlist, paramNum);
529 for (; paramNum; paramNum--)
530 {
531 temp = va_arg(vlist, u32);
532 if (temp == now)
533 {
534 result = WM_ERRCODE_SUCCESS;
535 }
536 }
537 va_end(vlist);
538
539 if (result == WM_ERRCODE_ILLEGAL_STATE)
540 {
541 WM_WARNING("WM state is \"%d\" now. So can't execute request.\n", now);
542 }
543
544 return result;
545 }
546
547 /*---------------------------------------------------------------------------*
548 Name: WmReceiveFifo
549
550 Description: Receives a callback from WM7 via FIFO.
551
552 Arguments: tag: Unused
553 fifo_buf_adr: Pointer to the callback parameter group
554 err: Unused
555
556 Returns: None.
557 *---------------------------------------------------------------------------*/
WmReceiveFifo(PXIFifoTag tag,u32 fifo_buf_adr,BOOL err)558 static void WmReceiveFifo(PXIFifoTag tag, u32 fifo_buf_adr, BOOL err)
559 {
560 #pragma unused( tag )
561
562 WMCallback *callback_p = (WMCallback *)fifo_buf_adr;
563 WMArm9Buf *w9b = wm9buf; // Notify compiler that it is not volatile
564 #ifdef WM_DEBUG_CALLBACK
565 int beginVcount = GX_GetVCount();
566 #endif
567
568 if (err)
569 return; // The WM_sp_init PXI handler is not ready
570
571 // Invalidates the FIFO command buffer (9 <- 7) cache
572 DC_InvalidateRange(w9b->fifo7to9, WM_FIFO_BUF_SIZE);
573 if (!w9b->scanOnlyFlag)
574 {
575 DC_InvalidateRange(w9b->status, WM_STATUS_BUF_SIZE);
576 }
577
578 // Checks if the response buffer is a different buffer from fifo7to9
579 if ((u32)callback_p != (u32)(w9b->fifo7to9))
580 {
581 DC_InvalidateRange(callback_p, WM_FIFO_BUF_SIZE);
582 }
583
584
585 if (callback_p->apiid >= WM_NUM_OF_CALLBACK)
586 {
587 if (callback_p->apiid == WM_APIID_INDICATION)
588 {
589 if (callback_p->errcode == WM_ERRCODE_FLASH_ERROR)
590 {
591 // ARM9 freeze
592 OS_Terminate(); // It does not return
593 }
594 if (w9b->indCallback != NULL)
595 {
596 w9b->indCallback((void *)callback_p);
597 }
598 }
599 else if (callback_p->apiid == WM_APIID_PORT_RECV)
600 {
601 // Performs callback processing according to the port number
602 WMPortRecvCallback *cb_Port = (WMPortRecvCallback *)callback_p;
603 SDK_ASSERT(cb_Port->port < 16);
604 // Notify if a callback has been registered
605 if (w9b->portCallbackTable[cb_Port->port] != NULL)
606 {
607 cb_Port->arg = w9b->portCallbackArgument[cb_Port->port];
608 cb_Port->connectedAidBitmap = (u16)w9b->connectedAidBitmap;
609 DC_InvalidateRange(cb_Port->recvBuf, w9b->status->mp_recvBufSize); // TODO: Too much is being invalidated here
610 (w9b->portCallbackTable[cb_Port->port]) ((void *)cb_Port);
611 }
612 #ifdef WM_DEBUG
613 else
614 {
615 WM_DPRINTF("Warning: no callback function on port %d { %04x %04x ... }\n",
616 cb_Port->port, cb_Port->data[0], cb_Port->data[1]);
617 }
618 #endif
619 }
620 else if (callback_p->apiid == WM_APIID_PORT_SEND)
621 {
622 // Performs the callback specified when the data is set
623 WMPortSendCallback *cb_Port = (WMPortSendCallback *)callback_p;
624 callback_p->apiid = WM_APIID_SET_MP_DATA; // Camouflages
625 if (cb_Port->callback != NULL)
626 {
627 (cb_Port->callback) ((void *)cb_Port);
628 }
629 }
630 else
631 {
632 OS_TPrintf("ARM9: no callback function\n");
633
634 }
635 }
636 else
637 {
638 // Invalidates the cache of the receive buffer
639 // When PORT_RECV is called after MPEND_IND and MP_IND, InvalidateRange has already been done, so there is no need to be concerned with the cache again.
640 //
641 if (callback_p->apiid == WM_APIID_START_MP)
642 {
643 WMStartMPCallback *cb_StartMP = (WMStartMPCallback *)callback_p;
644 if (cb_StartMP->state == WM_STATECODE_MPEND_IND
645 || cb_StartMP->state == WM_STATECODE_MP_IND)
646 {
647 if (cb_StartMP->errcode == WM_ERRCODE_SUCCESS)
648 {
649 DC_InvalidateRange(cb_StartMP->recvBuf, w9b->status->mp_recvBufSize);
650 }
651 }
652 }
653
654 // Remove the sleep callback if WM_Enable failed or WM_Disable succeeded
655 if( ( (callback_p->apiid == WM_APIID_DISABLE || callback_p->apiid == WM_APIID_END) && callback_p->errcode == WM_ERRCODE_SUCCESS) ||
656 ( (callback_p->apiid == WM_APIID_ENABLE || callback_p->apiid == WM_APIID_INITIALIZE) && callback_p->errcode != WM_ERRCODE_SUCCESS) )
657 {
658 WMi_DeleteSleepCallback();
659 }
660
661 // WM_End post-processing
662 if (callback_p->apiid == WM_APIID_END)
663 {
664 if (callback_p->errcode == WM_ERRCODE_SUCCESS)
665 {
666 WMCallbackFunc cb = w9b->CallbackTable[callback_p->apiid];
667 // Close WM library
668 (void)WM_Finish();
669 if (cb != NULL)
670 {
671 cb((void *)callback_p);
672 }
673
674 WM_DLOGF_CALLBACK("Cb[%x]", callback_p->apiid);
675
676 return;
677 }
678 }
679
680 #if 0
681 // Post-processing for WM_Reset, WM_Disconnect, and WM_EndParent
682 if (callback_p->apiid == WM_APIID_RESET
683 || callback_p->apiid == WM_APIID_DISCONNECT || callback_p->apiid == WM_APIID_END_PARENT)
684 {
685 if (w9b->connectedAidBitmap != 0)
686 {
687 WM_WARNING("connectedAidBitmap should be 0, but %04x", w9b->connectedAidBitmap);
688 }
689 w9b->myAid = 0;
690 w9b->connectedAidBitmap = 0;
691 }
692 #endif
693
694 // Callback processing according to apiid (does nothing if callback not set (NULL))
695 if (NULL != w9b->CallbackTable[callback_p->apiid])
696 {
697 (w9b->CallbackTable[callback_p->apiid]) ((void *)callback_p);
698 /* If WM_Finish was called in user callback and working memory was cleared, end here */
699 if (!wmInitialized)
700 {
701 return;
702 }
703 }
704 // Post-processing
705 // Process the messages so that the callback for the port can also be notified regarding connections/disconnections.
706 if (callback_p->apiid == WM_APIID_START_PARENT
707 || callback_p->apiid == WM_APIID_START_CONNECT)
708 {
709 u16 state, aid, myAid, reason;
710 u8 *macAddress;
711 u8 *ssid;
712 u16 parentSize, childSize;
713
714 if (callback_p->apiid == WM_APIID_START_PARENT)
715 {
716 WMStartParentCallback *cb = (WMStartParentCallback *)callback_p;
717 state = cb->state;
718 aid = cb->aid;
719 myAid = 0;
720 macAddress = cb->macAddress;
721 ssid = cb->ssid;
722 reason = cb->reason;
723 parentSize = cb->parentSize;
724 childSize = cb->childSize;
725 }
726 else if (callback_p->apiid == WM_APIID_START_CONNECT)
727 {
728 WMStartConnectCallback *cb = (WMStartConnectCallback *)callback_p;
729 state = cb->state;
730 aid = 0;
731 myAid = cb->aid;
732 macAddress = cb->macAddress;
733 ssid = NULL;
734 reason = cb->reason;
735 parentSize = cb->parentSize;
736 childSize = cb->childSize;
737 }
738 if (state == WM_STATECODE_CONNECTED ||
739 state == WM_STATECODE_DISCONNECTED
740 || state == WM_STATECODE_DISCONNECTED_FROM_MYSELF)
741 {
742 // Because this is inside the interrupt handler, there's no problem if it is static
743 static WMPortRecvCallback cb_Port;
744 u16 iPort;
745
746 // Change the connection status being managed on the WM9 side
747 if (state == WM_STATECODE_CONNECTED)
748 {
749 #ifdef WM_DEBUG
750 if (w9b->connectedAidBitmap & (1 << aid))
751 {
752 WM_DPRINTF("Warning: someone is connecting to connected aid: %d (%04x)",
753 aid, w9b->connectedAidBitmap);
754 }
755 #endif
756 WM_DLOGF_AIDBITMAP("aid(%d) connected: %04x -> %04x", aid,
757 w9b->connectedAidBitmap,
758 w9b->connectedAidBitmap | (1 << aid));
759 w9b->connectedAidBitmap |= (1 << aid);
760 }
761 else // WM_STATECODE_DISCONNECTED || WM_STATECODE_DISCONNECTED_FROM_MYSELF
762 {
763 #ifdef WM_DEBUG
764 if (!(w9b->connectedAidBitmap & (1 << aid)))
765 {
766 WM_DPRINTF
767 ("Warning: someone is disconnecting to disconnected aid: %d (%04x)",
768 aid, w9b->connectedAidBitmap);
769 }
770 #endif
771 WM_DLOGF_AIDBITMAP("aid(%d) disconnected: %04x -> %04x", aid,
772 w9b->connectedAidBitmap,
773 w9b->connectedAidBitmap & ~(1 << aid));
774 w9b->connectedAidBitmap &= ~(1 << aid);
775 }
776 w9b->myAid = myAid;
777
778 MI_CpuClear8(&cb_Port, sizeof(WMPortRecvCallback));
779 cb_Port.apiid = WM_APIID_PORT_RECV;
780 cb_Port.errcode = WM_ERRCODE_SUCCESS;
781 cb_Port.state = state;
782 cb_Port.recvBuf = NULL;
783 cb_Port.data = NULL;
784 cb_Port.length = 0;
785 cb_Port.aid = aid;
786 cb_Port.myAid = myAid;
787 cb_Port.connectedAidBitmap = (u16)w9b->connectedAidBitmap;
788 cb_Port.seqNo = 0xffff;
789 cb_Port.reason = reason;
790 MI_CpuCopy8(macAddress, cb_Port.macAddress, WM_SIZE_MACADDR);
791 if (ssid != NULL)
792 {
793 MI_CpuCopy16(ssid, cb_Port.ssid, WM_SIZE_CHILD_SSID);
794 }
795 else
796 {
797 MI_CpuClear16(cb_Port.ssid, WM_SIZE_CHILD_SSID);
798 }
799 cb_Port.maxSendDataSize = (u16)((myAid == 0) ? parentSize : childSize);
800 cb_Port.maxRecvDataSize = (u16)((myAid == 0) ? childSize : parentSize);
801
802 // Notify all ports of connections/disconnections
803 for (iPort = 0; iPort < WM_NUM_OF_PORT; iPort++)
804 {
805 cb_Port.port = iPort;
806 if (w9b->portCallbackTable[iPort] != NULL)
807 {
808 cb_Port.arg = w9b->portCallbackArgument[iPort];
809 (w9b->portCallbackTable[iPort]) ((void *)&cb_Port);
810 }
811 }
812 }
813 }
814 }
815 // The fifo7to9 region has been written with PORT_SEND and PORT_RECV, so the cache is invalidated so as to not be written back
816 //
817 DC_InvalidateRange(w9b->fifo7to9, WM_FIFO_BUF_SIZE);
818 WmClearFifoRecvFlag();
819
820 // If the response buffer is a different buffer from fifo7to9, camouflage the request reception completion flag
821 if ((u32)callback_p != (u32)(w9b->fifo7to9))
822 {
823 callback_p->apiid |= WM_API_REQUEST_ACCEPTED;
824 DC_StoreRange(callback_p, WM_FIFO_BUF_SIZE);
825 }
826
827 WM_DLOGF2_CALLBACK(beginVcount, "[CB](%x)", callback_p->apiid);
828
829 return;
830 }
831
832 /*---------------------------------------------------------------------------*
833 Name: WmClearFifoRecvFlag
834
835 Description: Notifies WM7 that reference to the FIFO data used in the WM7 callback is complete.
836
837 When using FIFO for callback in WM7, edit the next callback after waiting for this flag to unlock.
838
839
840 Arguments: None.
841
842 Returns: None.
843 *---------------------------------------------------------------------------*/
WmClearFifoRecvFlag(void)844 static void WmClearFifoRecvFlag(void)
845 {
846 if (OS_GetSystemWork()->wm_callback_control & WM_EXCEPTION_CB_MASK)
847 {
848 // Clears the CB exclusion flag
849 OS_GetSystemWork()->wm_callback_control &= ~WM_EXCEPTION_CB_MASK;
850 }
851 }
852
853 /*---------------------------------------------------------------------------*
854 Name: WMi_DebugPrintSendQueue
855
856 Description: Print outputs the content of the port send queue.
857
858 Arguments: queue: Pointer to the port send queue
859
860 Returns: None.
861 *---------------------------------------------------------------------------*/
WMi_DebugPrintSendQueue(WMPortSendQueue * queue)862 void WMi_DebugPrintSendQueue(WMPortSendQueue *queue)
863 {
864 WMstatus *status = wm9buf->status;
865 WMPortSendQueueData *queueData;
866 u16 index;
867
868 DC_InvalidateRange(wm9buf->status, WM_STATUS_BUF_SIZE); // Invalidates the ARM7 status region cache
869 queueData = status->sendQueueData;
870
871 OS_TPrintf("head = %d, tail = %d, ", queue->head, queue->tail);
872 if (queue->tail != WM_SEND_QUEUE_END)
873 {
874 OS_TPrintf("%s", (queueData[queue->tail].next == WM_SEND_QUEUE_END) ? "valid" : "invalid");
875 }
876 OS_TPrintf("\n");
877 for (index = queue->head; index != WM_SEND_QUEUE_END; index = queueData[index].next)
878 {
879 WMPortSendQueueData *data = &(queueData[index]);
880
881 OS_TPrintf("queueData[%d] -> %d { port=%d, destBitmap=%x, size=%d } \n", index, data->next,
882 data->port, data->destBitmap, data->size);
883 }
884
885 }
886
887 /*---------------------------------------------------------------------------*
888 Name: WMi_DebugPrintAllSendQueue
889
890 Description: Print outputs the content of all port send queues.
891
892 Arguments: None.
893
894 Returns: None.
895 *---------------------------------------------------------------------------*/
WMi_DebugPrintAllSendQueue(void)896 void WMi_DebugPrintAllSendQueue(void)
897 {
898 WMstatus *status = wm9buf->status;
899 #if 0
900 int iPrio;
901
902 DC_InvalidateRange(wm9buf->status, WM_STATUS_BUF_SIZE); // Invalidates the ARM7 status region cache
903 for (iPrio = 0; iPrio < WM_PRIORITY_LEVEL; iPrio++)
904 {
905 OS_TPrintf("== send queue [%d]\n", iPrio);
906 WMi_DebugPrintSendQueue(&status->sendQueue[iPrio]);
907 }
908 for (iPrio = 0; iPrio < WM_PRIORITY_LEVEL; iPrio++)
909 {
910 OS_TPrintf("== ready queue [%d]\n", iPrio);
911 WMi_DebugPrintSendQueue(&status->readyQueue[iPrio]);
912 }
913 OS_TPrintf("== free queue\n");
914 OS_TPrintf(" head: %d, tail: %d\n", status->sendQueueFreeList.head,
915 status->sendQueueFreeList.tail);
916 // WMi_DebugPrintSendQueue( &status->sendQueueFreeList );
917 #else
918 DC_InvalidateRange(wm9buf->status, WM_STATUS_BUF_SIZE); // Invalidates the ARM7 status region cache
919 OS_TPrintf("== ready queue [2]\n");
920 OS_TPrintf(" head: %d, tail: %d\n", status->readyQueue[2].head, status->readyQueue[2].tail);
921 #endif
922
923 }
924
925 /*---------------------------------------------------------------------------*
926 Name: WMi_GetStatusAddress
927
928 Description: Gets the pointer to the status structure managed internally by WM.
929 This structure is directly operated by ARM7, so writing by ARM9 is prohibited.
930 Also, note that the cache line containing the portion to be referenced needs to be deleted before referencing the contents.
931
932
933 Arguments: None.
934
935 Returns: const WMStatus*: Returns a pointer to the status structure.
936 *---------------------------------------------------------------------------*/
WMi_GetStatusAddress(void)937 const WMStatus *WMi_GetStatusAddress(void)
938 {
939 // Initialization check
940 if (WMi_CheckInitialized() != WM_ERRCODE_SUCCESS)
941 {
942 return NULL;
943 }
944
945 return wm9buf->status;
946 }
947
948 /*---------------------------------------------------------------------------*
949 Name: WMi_CheckMpPacketTimeRequired
950
951 Description: Confirms that no more than 5,600 microseconds are needed to send a single MP communication packet.
952
953
954 Arguments: parentSize: Size of parent transfer data
955 childSize: Size of child transfer data
956 childs: Number of child devices to communicate with
957
958 Returns: BOOL: If within the acceptable range, returns TRUE.
959 If it exceeds 5600 microseconds, returns FALSE.
960 *---------------------------------------------------------------------------*/
WMi_CheckMpPacketTimeRequired(u16 parentSize,u16 childSize,u8 childs)961 BOOL WMi_CheckMpPacketTimeRequired(u16 parentSize, u16 childSize, u8 childs)
962 {
963 s32 mp_time;
964
965 // Calculate the time it takes for one MP communication in units of microseconds
966 mp_time = (( // --- Parent send portion ---
967 96 // Preamble
968 + (24 // 802.11 Header
969 + 4 // TXOP + PollBitmap
970 + 2 // wmHeader
971 + parentSize + 4 // wmFooter( parent )
972 + 4 // FCS
973 ) * 4 // 4 microseconds per byte
974 ) + ( // --- Child send portion ---
975 (10 // SIFS
976 + 96 // Preamble
977 + (24 // 802.11 Header
978 + 2 // wmHeader
979 + childSize + 2 // wmFooter( child )
980 + 4 // FCS
981 ) * 4 // 4 microseconds per byte
982 + 6 // time to spare
983 ) * childs) + ( // --- MP ACK send portion ---
984 10 // SIFS
985 + 96 // Preamble
986 + (24 // 802.11 Header
987 + 4 // ACK
988 + 4 // FCS
989 ) * 4 // 4microseconds per byte
990 ));
991
992 if (mp_time > WM_MAX_MP_PACKET_TIME)
993 {
994 OS_TWarning
995 ("It is required %dus to transfer each MP packet.\nThat should not exceed %dus.\n",
996 mp_time, WM_MAX_MP_PACKET_TIME);
997 return FALSE;
998 }
999 return TRUE;
1000 }
1001
1002 /*---------------------------------------------------------------------------*
1003 Name: WMi_IsMP
1004
1005 Description: Gets current MP communication state.
1006
1007 Arguments: None.
1008
1009 Returns: TRUE if in MP communication state.
1010 *---------------------------------------------------------------------------*/
WMi_IsMP(void)1011 BOOL WMi_IsMP(void)
1012 {
1013 WMStatus *status;
1014 BOOL isMP;
1015 OSIntrMode e;
1016
1017 #ifdef SDK_DEBUG
1018 // Initialization check
1019 if (WMi_CheckInitialized() != WM_ERRCODE_SUCCESS)
1020 {
1021 return FALSE;
1022 }
1023 #endif
1024
1025 // Prohibit interrupts
1026 e = OS_DisableInterrupts();
1027
1028 if (wm9buf != NULL)
1029 {
1030 status = wm9buf->status;
1031 DC_InvalidateRange(&(status->mp_flag), 4);
1032 isMP = status->mp_flag;
1033 }
1034 else
1035 {
1036 isMP = FALSE;
1037 }
1038
1039 // End prohibiting of interrupts
1040 (void)OS_RestoreInterrupts(e);
1041
1042 return isMP;
1043 }
1044
1045 /*---------------------------------------------------------------------------*
1046 Name: WM_GetAID
1047
1048 Description: Gets current AID.
1049 Return a valid value only when the state is either PARENT, MP_PARENT, CHILD, or MP_CHILD.
1050
1051
1052 Arguments: None.
1053
1054 Returns: AID
1055 *---------------------------------------------------------------------------*/
WM_GetAID(void)1056 u16 WM_GetAID(void)
1057 {
1058 u16 myAid;
1059 OSIntrMode e;
1060
1061 #ifdef SDK_DEBUG
1062 // Initialization check
1063 if (WMi_CheckInitialized() != WM_ERRCODE_SUCCESS)
1064 {
1065 return 0;
1066 }
1067 #endif
1068
1069 // Prohibit interrupts
1070 e = OS_DisableInterrupts();
1071
1072 if (wm9buf != NULL)
1073 {
1074 myAid = wm9buf->myAid;
1075 }
1076 else
1077 {
1078 myAid = 0;
1079 }
1080
1081 // End prohibiting of interrupts
1082 (void)OS_RestoreInterrupts(e);
1083
1084 return myAid;
1085 }
1086
1087 /*---------------------------------------------------------------------------*
1088 Name: WM_GetConnectedAIDs
1089
1090 Description: Gets the currently connected partners in bitmap format.
1091 Return a valid value only when the state is either PARENT, MP_PARENT, CHILD, or MP_CHILD.
1092
1093 For a child device, returns 0x0001 when the child is connected to a parent.
1094
1095 Arguments: None.
1096
1097 Returns: Bitmap of AIDs of connected partners.
1098 *---------------------------------------------------------------------------*/
WM_GetConnectedAIDs(void)1099 u16 WM_GetConnectedAIDs(void)
1100 {
1101 u32 connectedAidBitmap;
1102 OSIntrMode e;
1103
1104 #ifdef SDK_DEBUG
1105 // Initialization check
1106 if (WMi_CheckInitialized() != WM_ERRCODE_SUCCESS)
1107 {
1108 return 0;
1109 }
1110 #endif
1111
1112 // Prohibit interrupts
1113 e = OS_DisableInterrupts();
1114
1115 if (wm9buf != NULL)
1116 {
1117 connectedAidBitmap = wm9buf->connectedAidBitmap;
1118 }
1119 else
1120 {
1121 connectedAidBitmap = 0;
1122 }
1123
1124 // End prohibiting of interrupts
1125 (void)OS_RestoreInterrupts(e);
1126
1127 #ifdef WM_DEBUG
1128 /*
1129 if (WMi_CheckStateEx(4, WM_STATE_PARENT, WM_STATE_CHILD, WM_STATE_MP_PARENT, WM_STATE_MP_CHILD)
1130 != WM_ERRCODE_SUCCESS && connectedAidBitmap != 0)
1131 {
1132 WM_WARNING("connectedAidBitmap should be 0, but %04x", connectedAidBitmap);
1133 }
1134 */
1135 #endif
1136
1137 return (u16)connectedAidBitmap;
1138 }
1139
1140 /*---------------------------------------------------------------------------*
1141 Name: WMi_GetMPReadyAIDs
1142
1143 Description: From among the currently connected parties, gets a list in bitmap format of the AIDs of parties which can receive MP.
1144
1145 Return a valid value only when the state is either PARENT, MP_PARENT, CHILD, or MP_CHILD.
1146
1147 For a child device, returns 0x0001 when the child is connected to a parent.
1148
1149 Arguments: None.
1150
1151 Returns: Bitmap of the AIDs of partners with which MP is started.
1152 *---------------------------------------------------------------------------*/
WMi_GetMPReadyAIDs(void)1153 u16 WMi_GetMPReadyAIDs(void)
1154 {
1155 WMStatus *status;
1156 u16 mpReadyAidBitmap;
1157 OSIntrMode e;
1158
1159 #ifdef SDK_DEBUG
1160 // Initialization check
1161 if (WMi_CheckInitialized() != WM_ERRCODE_SUCCESS)
1162 {
1163 return FALSE;
1164 }
1165 #endif
1166
1167 // Prohibit interrupts
1168 e = OS_DisableInterrupts();
1169
1170 if (wm9buf != NULL)
1171 {
1172 status = wm9buf->status;
1173 DC_InvalidateRange(&(status->mp_readyBitmap), 2);
1174 mpReadyAidBitmap = status->mp_readyBitmap;
1175 }
1176 else
1177 {
1178 mpReadyAidBitmap = FALSE;
1179 }
1180
1181 // End prohibiting of interrupts
1182 (void)OS_RestoreInterrupts(e);
1183
1184 return mpReadyAidBitmap;
1185 }
1186
1187 /*---------------------------------------------------------------------------*
1188 Name: WMi_RegisterSleepCallback
1189
1190 Description: Registers the callback function that will be run when shifting to Sleep Mode.
1191
1192 Arguments: None.
1193
1194 Returns: None.
1195 *---------------------------------------------------------------------------*/
WMi_RegisterSleepCallback(void)1196 void WMi_RegisterSleepCallback(void)
1197 {
1198 PM_SetSleepCallbackInfo(&sleepCbInfo, WmSleepCallback, NULL);
1199 PMi_InsertPreSleepCallbackEx(&sleepCbInfo, PM_CALLBACK_PRIORITY_WM );
1200 }
1201
1202 /*---------------------------------------------------------------------------*
1203 Name: WMi_DeleteSleepCallback
1204
1205 Description: Deletes the callback function that is run when shifting to Sleep Mode.
1206
1207 Arguments: None.
1208
1209 Returns: None.
1210 *---------------------------------------------------------------------------*/
WMi_DeleteSleepCallback(void)1211 void WMi_DeleteSleepCallback(void)
1212 {
1213 PM_DeletePreSleepCallback( &sleepCbInfo );
1214 }
1215
1216 /*---------------------------------------------------------------------------*
1217 Name: WmSleepCallback
1218
1219 Description: Prevents the program from entering Sleep Mode during wireless communications.
1220
1221 Arguments: None.
1222
1223 Returns: None.
1224 *---------------------------------------------------------------------------*/
WmSleepCallback(void *)1225 static void WmSleepCallback(void *)
1226 {
1227 /* ---------------------------------------------- *
1228 * As described in section 6.5 of the Programming Guidelines, it is prohibited to run the OS_GoSleepMode function during wireless communications
1229 *
1230 *
1231 * ---------------------------------------------- */
1232 OS_TPanic("Could not sleep during wireless communications.");
1233 }
1234
1235 #ifdef SDK_TWL
1236 /*---------------------------------------------------------------------------*
1237 Name: WM_GetWirelessCommFlag
1238
1239 Description: Checks whether wireless communications can be performed now.
1240
1241 Arguments: None.
1242
1243 Returns: WM_WIRELESS_COMM_FLAG_OFF: Wireless communications are not allowed.
1244 WM_WIRELESS_COMM_FLAG_ON: Wireless communications are allowed.
1245 WM_WIRELESS_COMM_FLAG_UNKNOWN: This cannot be determined because the program is running on a Nintendo DS system.
1246 *---------------------------------------------------------------------------*/
WM_GetWirelessCommFlag(void)1247 u8 WM_GetWirelessCommFlag( void )
1248 {
1249 u8 result = WM_WIRELESS_COMM_FLAG_UNKNOWN;
1250
1251 if( OS_IsRunOnTwl() )
1252 {
1253 if( WMi_CheckEnableFlag() )
1254 {
1255 result = WM_WIRELESS_COMM_FLAG_ON;
1256 }
1257 else
1258 {
1259 result = WM_WIRELESS_COMM_FLAG_OFF;
1260 }
1261 }
1262
1263 return result;
1264 }
1265
1266 /*---------------------------------------------------------------------------*
1267 Name: WMi_CheckEnableFlag
1268
1269 Description: Checks the flag that allows wireless use, configurable from the TWL System Settings.
1270
1271 Arguments: None.
1272
1273 Returns: TRUE if wireless features can be used and FALSE otherwise
1274 *---------------------------------------------------------------------------*/
WMi_CheckEnableFlag(void)1275 BOOL WMi_CheckEnableFlag(void)
1276 {
1277
1278 if( OS_IsAvailableWireless() == TRUE && OS_IsForceDisableWireless() == FALSE )
1279 {
1280 return TRUE;
1281 }
1282 return FALSE;
1283 }
1284 #endif
1285
1286 /*---------------------------------------------------------------------------*
1287 End of file
1288 *---------------------------------------------------------------------------*/
1289