• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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