1 /*
2 * osapi.c
3 *
4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35 /*
36 * src/osapi.c
37 *
38 */
39 #include "tidef.h"
40 #include "arch_ti.h"
41
42 #include <linux/stddef.h>
43 #include <linux/string.h>
44 #include <linux/time.h>
45 #include <linux/timer.h>
46 #include <linux/module.h>
47 #include <linux/kernel.h>
48 #include <linux/netdevice.h>
49 #include <linux/completion.h>
50 #include <linux/etherdevice.h>
51 #include <linux/vmalloc.h>
52 #include <linux/string.h>
53 #include <linux/delay.h>
54 #include <linux/time.h>
55 #include <linux/list.h>
56 #include <stdarg.h>
57 #include <asm/io.h>
58 #include "RxBuf_linux.h"
59
60 /*#include "debug_module.h"*/
61 #include "host_platform.h"
62 #include "WlanDrvIf.h"
63 #include "bmtrace_api.h"
64 #include "TI_IPC_Api.h"
65 #include "802_11Defs.h"
66 #include "osApi.h"
67 #include "txMgmtQueue_Api.h"
68 #include "EvHandler.h"
69
70 #ifdef ESTA_TIMER_DEBUG
71 #define esta_timer_log(fmt,args...) printk(fmt, ## args)
72 #else
73 #define esta_timer_log(fmt,args...)
74 #endif
75
76 #define FRAG_SIZE 200
77
78 typedef struct timer_list TOsTimer;
79
80 TI_BOOL bRedirectOutputToLogger = TI_FALSE;
81 TI_BOOL use_debug_module = TI_FALSE;
82
83 /****************************************************************************************
84 * *
85 * OS Report API *
86 * *
87 ****************************************************************************************/
SendLoggerData(TI_HANDLE OsContext,TI_UINT8 * pMsg,TI_UINT16 len)88 static void SendLoggerData (TI_HANDLE OsContext, TI_UINT8 *pMsg, TI_UINT16 len)
89 {
90 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
91
92 if (len > 0)
93 {
94 EvHandlerSendEvent(drv->tCommon.hEvHandler, IPC_EVENT_LOGGER, pMsg, len);
95 }
96 }
97
os_setDebugOutputToLogger(TI_BOOL value)98 void os_setDebugOutputToLogger(TI_BOOL value)
99 {
100 bRedirectOutputToLogger = value;
101 }
102 /****************************************************************************************
103 * os_setDebugMode()
104 ****************************************************************************************
105 DESCRIPTION: Set the Debug Mode
106
107 INPUT:
108
109 RETURN: None
110
111 NOTES:
112 *****************************************************************************************/
os_setDebugMode(TI_BOOL enable)113 void os_setDebugMode(TI_BOOL enable)
114 {
115 use_debug_module = enable;
116 }
117
118
119 /****************************************************************************************
120 * os_printf()
121 ****************************************************************************************
122 DESCRIPTION: Print formatted output.
123
124 INPUT: format - Specifies the string, to be printed
125
126 RETURN: None
127
128 NOTES:
129 *****************************************************************************************/
os_printf(const char * format,...)130 void os_printf(const char *format ,...)
131 {
132 static int from_new_line = 1; /* Used to save the last message EOL */
133 va_list ap;
134 static char msg[MAX_MESSAGE_SIZE];
135 char *p_msg = msg; /* Pointer to the message */
136 TI_UINT16 message_len;
137 TI_UINT32 sec = 0;
138 TI_UINT32 uSec = 0;
139 os_memoryZero(NULL,msg, MAX_MESSAGE_SIZE);
140
141 /* Format the message and keep the message length */
142 va_start(ap,format);
143 message_len = vsnprintf(&msg[0], sizeof(msg) -1 , format, ap);
144 if( from_new_line )
145 {
146 if (msg[1] == '$')
147 {
148 p_msg += 4;
149 }
150
151 sec = os_timeStampUs(NULL);
152 uSec = sec % MICROSECOND_IN_SECONDS;
153 sec /= MICROSECOND_IN_SECONDS;
154
155 printk(KERN_INFO DRIVER_NAME ": %d.%06d: %s",sec,uSec,p_msg);
156 }
157 else
158 {
159 printk(&msg[0]);
160 }
161
162 from_new_line = ( msg[message_len] == '\n' );
163 va_end(ap);
164 }
165
166 /****************************************************************************************
167 * *
168 * OS TIMER API *
169 * *
170 ****************************************************************************************/
171
172 /****************************************************************************************
173 * os_timerCreate()
174 ****************************************************************************************
175 DESCRIPTION: This function creates and initializes an OS timer object associated with a
176 caller's pRoutine function.
177
178 ARGUMENTS: OsContext - The OS handle
179 pRoutine - The user callback function
180 hFuncHandle - The user callback handle
181
182 RETURN: A handle of the created OS timer.
183
184 NOTES: 1) The user's callback is called directly from OS timer context when expired.
185 2) In some OSs, it may be needed to use an intermediate callback in the
186 osapi layer (use os_timerHandlr for that).
187
188 *****************************************************************************************/
os_timerCreate(TI_HANDLE OsContext,fTimerFunction pRoutine,TI_HANDLE hFuncHandle)189 TI_HANDLE os_timerCreate (TI_HANDLE OsContext, fTimerFunction pRoutine, TI_HANDLE hFuncHandle)
190 {
191 TOsTimer *pOsTimer = os_memoryAlloc (OsContext, sizeof(TOsTimer));
192
193 init_timer (pOsTimer);
194 pOsTimer->function = (void *)pRoutine;
195 pOsTimer->data = (int)hFuncHandle;
196
197 return (TI_HANDLE)pOsTimer;
198 }
199
200
201 /****************************************************************************************
202 * os_timerDestroy()
203 ****************************************************************************************
204 DESCRIPTION: This function destroys the OS timer object.
205
206 ARGUMENTS:
207
208 RETURN:
209
210 NOTES:
211 *****************************************************************************************/
os_timerDestroy(TI_HANDLE OsContext,TI_HANDLE TimerHandle)212 void os_timerDestroy (TI_HANDLE OsContext, TI_HANDLE TimerHandle)
213 {
214 os_timerStop (OsContext, TimerHandle);
215 os_memoryFree (OsContext, TimerHandle, sizeof(TOsTimer));
216 }
217
218
219 /****************************************************************************************
220 * os_timerStart()
221 ****************************************************************************************
222 DESCRIPTION: This function start the timer object.
223
224 ARGUMENTS:
225
226 RETURN:
227
228 NOTES:
229 *****************************************************************************************/
os_timerStart(TI_HANDLE OsContext,TI_HANDLE TimerHandle,TI_UINT32 DelayMs)230 void os_timerStart (TI_HANDLE OsContext, TI_HANDLE TimerHandle, TI_UINT32 DelayMs)
231 {
232 TI_UINT32 jiffie_cnt = msecs_to_jiffies (DelayMs);
233
234 mod_timer ((TOsTimer *)TimerHandle, jiffies + jiffie_cnt);
235 }
236
237
238 /****************************************************************************************
239 * os_stopTimer()
240 ****************************************************************************************
241 DESCRIPTION: This function stop the timer object.
242
243 ARGUMENTS:
244
245 RETURN:
246
247 NOTES:
248 *****************************************************************************************/
os_timerStop(TI_HANDLE OsContext,TI_HANDLE TimerHandle)249 void os_timerStop (TI_HANDLE OsContext, TI_HANDLE TimerHandle)
250 {
251 del_timer_sync((TOsTimer *)TimerHandle);
252 }
253
254
255 /****************************************************************************************
256 * os_periodicIntrTimerStart()
257 ****************************************************************************************
258 DESCRIPTION: This function starts the periodic interrupt mechanism. This mode is used
259 when interrupts that usually received from the Fw is now masked, and we are
260 checking for any need of Fw handling in time periods.
261
262 ARGUMENTS:
263
264 RETURN:
265
266 NOTES: Power level of the CHIP should be always awake in this mode (no ELP)
267 *****************************************************************************************/
268 #ifdef PRIODIC_INTERRUPT
os_periodicIntrTimerStart(TI_HANDLE OsContext)269 void os_periodicIntrTimerStart (TI_HANDLE OsContext)
270 {
271 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
272
273 mod_timer (drv->hPollTimer, jiffies + TIWLAN_IRQ_POLL_INTERVAL);
274 }
275 #endif
276
277
278 /****************************************************************************************
279 * os_timeStampMs()
280 ****************************************************************************************
281 DESCRIPTION: This function returns the number of milliseconds that have elapsed since
282 the system was booted.
283
284 ARGUMENTS: OsContext - our adapter context.
285
286 RETURN:
287
288 NOTES:
289 *****************************************************************************************/
os_timeStampMs(TI_HANDLE OsContext)290 TI_UINT32 os_timeStampMs (TI_HANDLE OsContext)
291 {
292 struct timeval tv;
293 do_gettimeofday(&tv);
294 return tv.tv_sec*1000 + tv.tv_usec/1000;
295 }
296
297
298 /****************************************************************************************
299 * os_timeStampUs()
300 ****************************************************************************************
301 DESCRIPTION: This function returns the number of microseconds that have elapsed since
302 the system was booted.
303
304 ARGUMENTS: OsContext - our adapter context.
305 Note that sometimes this function will be called with NULL(!!!) as argument!
306
307 RETURN:
308
309 NOTES:
310 *****************************************************************************************/
os_timeStampUs(TI_HANDLE OsContext)311 TI_UINT32 os_timeStampUs (TI_HANDLE OsContext)
312 {
313 struct timeval tv;
314 do_gettimeofday(&tv);
315 return tv.tv_sec*1000000 + tv.tv_usec;
316 }
317
318
319 /****************************************************************************************
320 * os_StalluSec()
321 ****************************************************************************************
322 DESCRIPTION: This function make delay in microseconds.
323
324 ARGUMENTS: OsContext - our adapter context.
325 uSec - delay time in microseconds
326
327 RETURN:
328
329 NOTES:
330 *****************************************************************************************/
os_StalluSec(TI_HANDLE OsContext,TI_UINT32 uSec)331 void os_StalluSec (TI_HANDLE OsContext, TI_UINT32 uSec)
332 {
333 udelay (uSec);
334 }
335
336
337 /****************************************************************************************
338 * *
339 * Protection services API *
340 * *
341 ****************************************************************************************
342 * OS protection is implemented as spin_lock_irqsave and spin_unlock_irqrestore *
343 ****************************************************************************************/
344
345
346 /****************************************************************************************
347 * os_protectCreate()
348 ****************************************************************************************
349 DESCRIPTION:
350
351 ARGUMENTS: OsContext - our adapter context.
352
353 RETURN: A handle of the created mutex/spinlock.
354 TI_HANDLE_INVALID if there is insufficient memory available or problems
355 initializing the mutex
356
357 NOTES:
358 *****************************************************************************************/
os_protectCreate(TI_HANDLE OsContext)359 TI_HANDLE os_protectCreate (TI_HANDLE OsContext)
360 {
361 return NULL;
362 }
363
364
365 /****************************************************************************************
366 * os_protectDestroy()
367 ****************************************************************************************
368 DESCRIPTION:
369
370 ARGUMENTS: OsContext - our adapter context.
371
372 RETURN: None - This had better work since there is not a return value to the user
373
374 NOTES:
375 *****************************************************************************************/
os_protectDestroy(TI_HANDLE OsContext,TI_HANDLE ProtectCtx)376 void os_protectDestroy (TI_HANDLE OsContext, TI_HANDLE ProtectCtx)
377 {
378 }
379
380
381 /****************************************************************************************
382 * os_protectLock()
383 ****************************************************************************************
384 DESCRIPTION:
385
386 ARGUMENTS: OsContext - our adapter context.
387
388 RETURN: None - This had better work since there is not a return value to the user
389
390 NOTES:
391 *****************************************************************************************/
os_protectLock(TI_HANDLE OsContext,TI_HANDLE ProtectContext)392 void os_protectLock (TI_HANDLE OsContext, TI_HANDLE ProtectContext)
393 {
394 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
395
396 spin_lock_irqsave (&drv->lock, drv->flags);
397 }
398
399
400 /****************************************************************************************
401 * os_protectUnlock()
402 ****************************************************************************************
403 DESCRIPTION:
404
405 ARGUMENTS: OsContext - our adapter context.
406
407 RETURN: None - This had better work since there is not a return value to the user
408
409 NOTES:
410 *****************************************************************************************/
os_protectUnlock(TI_HANDLE OsContext,TI_HANDLE ProtectContext)411 void os_protectUnlock (TI_HANDLE OsContext, TI_HANDLE ProtectContext)
412 {
413 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
414
415 spin_unlock_irqrestore (&drv->lock, drv->flags);
416 }
417 /****************************************************************************************
418 * os_receivePacket()
419 ****************************************************************************************
420 DESCRIPTION:
421
422 ARGUMENTS:
423
424 RETURN:
425
426 NOTES:
427 *****************************************************************************************/
os_receivePacket(TI_HANDLE OsContext,void * pPacket,TI_UINT16 Length)428 TI_BOOL os_receivePacket (TI_HANDLE OsContext, void* pPacket, TI_UINT16 Length)
429 {
430 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
431 unsigned char *pdata = (unsigned char *)((TI_UINT32)pPacket & ~(TI_UINT32)0x3);
432 rx_head_t *rx_head = (rx_head_t *)(pdata - WSPI_PAD_BYTES - RX_HEAD_LEN_ALIGNED);
433 struct sk_buff *skb = rx_head->skb;
434
435 #ifdef TI_DBG
436 if ((TI_UINT32)pPacket & 0x3)
437 {
438 if ((TI_UINT32)pPacket - (TI_UINT32)skb->data != 2)
439 {
440 printk("os_receivePacket() address error skb=0x%x skb->data=0x%x pPacket=0x%x !!!\n",(int)skb, (int)skb->data, (int)pPacket);
441 }
442 }
443 else
444 {
445 if ((TI_UINT32)skb->data != (TI_UINT32)pPacket)
446 {
447 printk("os_receivePacket() address error skb=0x%x skb->data=0x%x pPacket=0x%x !!!\n",(int)skb, (int)skb->data, (int)pPacket);
448 }
449 }
450 if (Length != RX_ETH_PKT_LEN(pPacket))
451 {
452 printk("os_receivePacket() Length=%d != RX_ETH_PKT_LEN(pPacket)=%d!!!\n",(int)Length, RX_ETH_PKT_LEN(pPacket));
453 }
454
455 #endif
456 /*
457 printk("-->> os_receivePacket() pPacket=0x%x Length=%d skb=0x%x skb->data=0x%x skb->head=0x%x skb->len=%d\n",
458 (int)pPacket, (int)Length, (int)skb, (int)skb->data, (int)skb->head, (int)skb->len);
459 */
460 /* Use skb_reserve, it updates both skb->data and skb->tail. */
461 skb->data = RX_ETH_PKT_DATA(pPacket);
462 skb->tail = skb->data;
463 skb_put(skb, RX_ETH_PKT_LEN(pPacket));
464 /*
465 printk("-->> os_receivePacket() skb=0x%x skb->data=0x%x skb->head=0x%x skb->len=%d\n",
466 (int)skb, (int)skb->data, (int)skb->head, (int)skb->len);
467 */
468 ti_nodprintf(TIWLAN_LOG_INFO, "os_receivePacket - Received EAPOL len-%d\n", WBUF_LEN(pWbuf));
469
470 skb->dev = drv->netdev;
471 skb->protocol = eth_type_trans(skb, drv->netdev);
472 skb->ip_summed = CHECKSUM_NONE;
473
474 drv->stats.rx_packets++;
475 drv->stats.rx_bytes += skb->len;
476
477 /* Send the skb to the TCP stack.
478 * it responsibly of the Linux kernel to free the skb
479 */
480 {
481 CL_TRACE_START_L1();
482
483 os_wake_lock_timeout_enable(drv);
484
485 netif_rx_ni(skb);
486
487 /* Note: Don't change this trace (needed to exclude OS processing from Rx CPU utilization) */
488 CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "RX", "");
489 }
490
491 return TI_TRUE;
492 }
493
494 /*-----------------------------------------------------------------------------
495
496 Routine Name: os_timerHandlr
497
498 Routine Description:
499
500 Just a place holder for timer expiration handling in other OSs.
501 In Linux, user callback is called directly on OS timer expiry.
502
503 Arguments: parm - timer object handle
504
505 Return Value: None.
506
507 Notes:
508
509 -----------------------------------------------------------------------------*/
os_timerHandlr(unsigned long parm)510 void os_timerHandlr(unsigned long parm)
511 {
512 /* Not needed in Linux (user callback is called directly on OS timer expiry). */
513 }
514
515
516 /*-----------------------------------------------------------------------------
517 Routine Name: os_connectionStatus
518
519 Routine Description:
520
521 The eSTA-DK will call this API so the OS stack is aware that the
522 WLAN layer is ready to function.
523
524 Arguments:
525 cStatus = 1; WLAN in ready for network packets
526 cStatus = 0; WLAN in not ready for network packets
527
528 Return Value: None
529 -----------------------------------------------------------------------------*/
os_IndicateEvent(TI_HANDLE OsContext,IPC_EV_DATA * pData)530 TI_INT32 os_IndicateEvent (TI_HANDLE OsContext, IPC_EV_DATA* pData)
531 {
532 IPC_EVENT_PARAMS *pInParam = &pData->EvParams;
533 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
534 /*TI_UINT8 AuthBuf[sizeof(TI_UINT32) + sizeof(OS_802_11_AUTHENTICATION_REQUEST)];*/
535
536 ti_nodprintf(TIWLAN_LOG_INFO, "\n os_ConnectionStatus Event 0x%08x \n", CsStatus->Event);
537
538 switch(pInParam->uEventType)
539 {
540 case IPC_EVENT_ASSOCIATED:
541 if (drv->netdev != NULL)
542 netif_carrier_on(drv->netdev);
543 break;
544
545 case IPC_EVENT_DISASSOCIATED:
546 if (drv->netdev != NULL)
547 netif_carrier_off(drv->netdev);
548 break;
549
550 case IPC_EVENT_LINK_SPEED:
551 drv->tCommon.uLinkSpeed = (*(TI_UINT32*)pData->uBuffer * 10000) / 2;
552 ti_nodprintf(TIWLAN_LOG_INFO, "\n Link Speed = 0x%08x \n",drv->tCommon.uLinkSpeed);
553 break;
554 }
555
556 return TI_OK;
557 }
558
559
560
561 /******************************************************************************/
562
os_disableIrq(TI_HANDLE OsContext)563 void os_disableIrq (TI_HANDLE OsContext)
564 {
565 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
566 disable_irq (drv->irq);
567 }
568
os_enableIrq(TI_HANDLE OsContext)569 void os_enableIrq (TI_HANDLE OsContext)
570 {
571 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
572 enable_irq (drv->irq);
573 }
574
575 /*-----------------------------------------------------------------------------
576 Routine Name: os_InterruptServiced
577
578 Routine Description: Called when IRQ line is not asserted any more
579 (i.e. we can enable IRQ in Level sensitive platform)
580
581 Arguments: OsContext - handle to OS context
582
583 Return Value: none
584 -----------------------------------------------------------------------------*/
os_InterruptServiced(TI_HANDLE OsContext)585 void os_InterruptServiced (TI_HANDLE OsContext)
586 {
587 /* To be implemented with Level IRQ */
588 }
589
590 /*-----------------------------------------------------------------------------
591 Routine Name: os_wake_lock_timeout
592
593 Routine Description: Called to prevent system from suspend for some time
594
595 Arguments: OsContext - handle to OS context
596
597 Return Value: packet counter
598 -----------------------------------------------------------------------------*/
os_wake_lock_timeout(TI_HANDLE OsContext)599 int os_wake_lock_timeout (TI_HANDLE OsContext)
600 {
601 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
602 int ret = 0;
603 unsigned long flags;
604
605 spin_lock_irqsave(&drv->lock, flags);
606 if (drv) {
607 ret = drv->wl_packet;
608 if (drv->wl_packet) {
609 drv->wl_packet = 0;
610 #ifdef CONFIG_HAS_WAKELOCK
611 wake_lock_timeout(&drv->wl_rxwake, (HZ >> 1));
612 #endif
613 }
614 }
615 spin_unlock_irqrestore(&drv->lock, flags);
616 /* printk("%s: %d\n", __func__, ret); */
617 return ret;
618 }
619
620 /*-----------------------------------------------------------------------------
621 Routine Name: os_wake_lock_timeout_enable
622
623 Routine Description: Called to set flag for suspend prevention for some time
624
625 Arguments: OsContext - handle to OS context
626
627 Return Value: packet counter
628 -----------------------------------------------------------------------------*/
os_wake_lock_timeout_enable(TI_HANDLE OsContext)629 int os_wake_lock_timeout_enable (TI_HANDLE OsContext)
630 {
631 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
632 unsigned long flags;
633 int ret;
634
635 spin_lock_irqsave(&drv->lock, flags);
636 ret = drv->wl_packet = 1;
637 spin_unlock_irqrestore(&drv->lock, flags);
638 return ret;
639 }
640
641 /*-----------------------------------------------------------------------------
642 Routine Name: os_wake_lock
643
644 Routine Description: Called to prevent system from suspend
645
646 Arguments: OsContext - handle to OS context
647
648 Return Value: wake_lock counter
649 -----------------------------------------------------------------------------*/
os_wake_lock(TI_HANDLE OsContext)650 int os_wake_lock (TI_HANDLE OsContext)
651 {
652 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
653 int ret = 0;
654 unsigned long flags;
655
656 spin_lock_irqsave(&drv->lock, flags);
657 if (drv) {
658 #ifdef CONFIG_HAS_WAKELOCK
659 if (!drv->wl_count)
660 wake_lock(&drv->wl_wifi);
661 #endif
662 drv->wl_count++;
663 ret = drv->wl_count;
664 }
665 spin_unlock_irqrestore(&drv->lock, flags);
666 /* printk("%s: %d\n", __func__, ret); */
667 return ret;
668 }
669
670 /*-----------------------------------------------------------------------------
671 Routine Name: os_wake_unlock
672
673 Routine Description: Called to allow system to suspend
674
675 Arguments: OsContext - handle to OS context
676
677 Return Value: wake_lock counter
678 -----------------------------------------------------------------------------*/
os_wake_unlock(TI_HANDLE OsContext)679 int os_wake_unlock (TI_HANDLE OsContext)
680 {
681 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
682 int ret = 0;
683 unsigned long flags;
684
685 spin_lock_irqsave(&drv->lock, flags);
686 if (drv && drv->wl_count) {
687 drv->wl_count--;
688 #ifdef CONFIG_HAS_WAKELOCK
689 if (!drv->wl_count)
690 wake_unlock(&drv->wl_wifi);
691 #endif
692 ret = drv->wl_count;
693 }
694 spin_unlock_irqrestore(&drv->lock, flags);
695 /* printk("%s: %d\n", __func__, ret); */
696 return ret;
697 }
698
699 /*-----------------------------------------------------------------------------
700 Routine Name: os_RequestSchedule
701
702 Routine Description:
703
704 Arguments:
705
706 Return Value: TI_OK
707 -----------------------------------------------------------------------------*/
os_RequestSchedule(TI_HANDLE OsContext)708 int os_RequestSchedule (TI_HANDLE OsContext)
709 {
710 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext;
711
712 /* Note: The performance trace below doesn't inclose the schedule
713 * itself because the rescheduling can occur immediately and call
714 * os_RequestSchedule again which will confuse the trace tools */
715 CL_TRACE_START_L3();
716 CL_TRACE_END_L3("tiwlan_drv.ko", "OS", "TASK", "");
717
718 if( !queue_work(drv->tiwlan_wq, &drv->tWork) ) {
719 /* printk("%s: Fail\n",__func__); */
720 return TI_NOK;
721 }
722
723 return TI_OK;
724 }
725
726
727 /*-----------------------------------------------------------------------------
728 Routine Name: os_SignalObjectCreate
729
730 Routine Description:
731
732 Arguments:
733
734 Return Value: TI_OK
735 -----------------------------------------------------------------------------*/
os_SignalObjectCreate(TI_HANDLE OsContext)736 void *os_SignalObjectCreate (TI_HANDLE OsContext)
737 {
738 struct completion *myPtr;
739 myPtr = os_memoryAlloc(OsContext, sizeof(struct completion));
740 if (myPtr)
741 init_completion (myPtr);
742 return (myPtr);
743 }
744
745
746 /*-----------------------------------------------------------------------------
747 Routine Name: os_SignalObjectWait
748
749 Routine Description:
750
751 Arguments:
752
753 Return Value: TI_OK
754 -----------------------------------------------------------------------------*/
os_SignalObjectWait(TI_HANDLE OsContext,void * signalObject)755 int os_SignalObjectWait (TI_HANDLE OsContext, void *signalObject)
756 {
757 if (!signalObject)
758 return TI_NOK;
759 wait_for_completion ((struct completion *)signalObject);
760 return TI_OK;
761 }
762
763
764 /*-----------------------------------------------------------------------------
765 Routine Name: os_SignalObjectSet
766
767 Routine Description:
768
769 Arguments:
770
771 Return Value: TI_OK
772 -----------------------------------------------------------------------------*/
os_SignalObjectSet(TI_HANDLE OsContext,void * signalObject)773 int os_SignalObjectSet (TI_HANDLE OsContext, void *signalObject)
774 {
775 if (!signalObject)
776 return TI_NOK;
777 complete ((struct completion *)signalObject);
778 return TI_OK;
779 }
780
781
782 /*-----------------------------------------------------------------------------
783 Routine Name: os_SignalObjectFree
784
785 Routine Description:
786
787 Arguments:
788
789 Return Value: TI_OK
790 -----------------------------------------------------------------------------*/
os_SignalObjectFree(TI_HANDLE OsContext,void * signalObject)791 int os_SignalObjectFree (TI_HANDLE OsContext, void *signalObject)
792 {
793 if (!signalObject)
794 return TI_NOK;
795 os_memoryFree(OsContext, signalObject, sizeof(struct completion));
796 return TI_OK;
797 }
798
799
800 /**
801 * \fn os_Trace
802 * \brief Prepare and send trace message to the logger.
803 *
804 * \param OsContext - The OS handle
805 * \param uLevel - Severity level of the trace message
806 * \param uFileId - Source file ID of the trace message
807 * \param uLineNum - Line number of the trace message
808 * \param uParamsNum - Number of parameters in the trace message
809 * \param ... - The trace message parameters
810 *
811 * \return void
812 */
os_Trace(TI_HANDLE OsContext,TI_UINT32 uLevel,TI_UINT32 uFileId,TI_UINT32 uLineNum,TI_UINT32 uParamsNum,...)813 void os_Trace (TI_HANDLE OsContext, TI_UINT32 uLevel, TI_UINT32 uFileId, TI_UINT32 uLineNum, TI_UINT32 uParamsNum, ...)
814 {
815 TI_UINT32 index;
816 TI_UINT32 uParam;
817 TI_UINT32 uMaxParamValue = 0;
818 TI_UINT32 uMsgLen = TRACE_MSG_MIN_LENGTH;
819 TI_UINT8 aMsg[TRACE_MSG_MAX_LENGTH] = {0};
820 TTraceMsg *pMsgHdr = (TTraceMsg *)&aMsg[0];
821 TI_UINT8 *pMsgData = &aMsg[0] + sizeof(TTraceMsg);
822 va_list list;
823
824 if (!bRedirectOutputToLogger)
825 {
826 return;
827 }
828
829 if (uParamsNum > TRACE_MSG_MAX_PARAMS)
830 {
831 uParamsNum = TRACE_MSG_MAX_PARAMS;
832 }
833
834 /* sync on the parameters */
835 va_start(list, uParamsNum);
836
837 /* find the longest parameter */
838 for (index = 0; index < uParamsNum; index++)
839 {
840 /* get parameter from the stack */
841 uParam = va_arg (list, TI_UINT32);
842
843 /* save the longest parameter at variable 'uMaxParamValue' */
844 if (uParam > uMaxParamValue)
845 {
846 uMaxParamValue = uParam;
847 }
848
849 /* 32 bit parameter is the longest possible - get out of the loop */
850 if (uMaxParamValue > UINT16_MAX_VAL)
851 {
852 break;
853 }
854 }
855
856 /* Set msg length and format according to the biggest parameter value (8/16/32 bits) */
857 if (uMaxParamValue > UINT16_MAX_VAL)
858 {
859 pMsgHdr->uFormat = TRACE_FORMAT_32_BITS_PARAMS;
860 uMsgLen += uParamsNum * sizeof(TI_UINT32);
861 }
862 else if (uMaxParamValue > UINT8_MAX_VAL)
863 {
864 pMsgHdr->uFormat = TRACE_FORMAT_16_BITS_PARAMS;
865 uMsgLen += uParamsNum * sizeof(TI_UINT16);
866 }
867 else
868 {
869 pMsgHdr->uFormat = TRACE_FORMAT_8_BITS_PARAMS;
870 uMsgLen += uParamsNum;
871 }
872
873 /* Fill all other header information */
874 pMsgHdr->uLevel = (TI_UINT8)uLevel;
875 pMsgHdr->uParamsNum = (TI_UINT8)uParamsNum;
876 pMsgHdr->uFileId = (TI_UINT16)uFileId;
877 pMsgHdr->uLineNum = (TI_UINT16)uLineNum;
878
879 /* re-sync on the parameters */
880 va_start(list, uParamsNum);
881
882 /* add the parameters */
883 for (index = 0; index < uParamsNum; index++)
884 {
885 /* get parameter from the stack */
886 uParam = va_arg(list, TI_UINT32);
887
888 /* insert the parameter and increment msg pointer */
889 switch(pMsgHdr->uFormat)
890 {
891 case TRACE_FORMAT_8_BITS_PARAMS:
892 INSERT_BYTE(pMsgData, uParam);
893 break;
894
895 case TRACE_FORMAT_16_BITS_PARAMS:
896 INSERT_2_BYTES(pMsgData, uParam);
897 break;
898
899 case TRACE_FORMAT_32_BITS_PARAMS:
900 INSERT_4_BYTES(pMsgData, uParam);
901 break;
902
903 default:
904 va_end(list);
905 return;
906 }
907 }
908
909 va_end(list);
910
911 /* Send the trace message to the logger */
912 SendLoggerData(OsContext, aMsg, (TI_UINT16)uMsgLen);
913 }
914
915 /*--------------------------------------------------------------------------------------*/
916
917 /**
918 * \fn os_SetDrvThreadPriority
919 * \brief Called upon init to set WLAN driver thread priority.
920 * Currently not supported in Linux.
921 *
922 * \param OsContext - The OS handle
923 * \param uWlanDrvThreadPriority - The WLAN driver thread priority
924 * \return
925 */
os_SetDrvThreadPriority(TI_HANDLE OsContext,TI_UINT32 uWlanDrvThreadPriority)926 void os_SetDrvThreadPriority (TI_HANDLE OsContext, TI_UINT32 uWlanDrvThreadPriority)
927 {
928 }
929