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 ****************************************************************************************/ 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 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 *****************************************************************************************/ 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 -----------------------------------------------------------------------------*/ 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 -----------------------------------------------------------------------------*/ 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 563 void os_disableIrq (TI_HANDLE OsContext) 564 { 565 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext; 566 disable_irq (drv->irq); 567 } 568 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 -----------------------------------------------------------------------------*/ 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 1 sec 594 595 Arguments: OsContext - handle to OS context 596 597 Return Value: packet counter 598 -----------------------------------------------------------------------------*/ 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 if (drv) { 606 spin_lock_irqsave(&drv->lock, flags); 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); 612 #endif 613 } 614 spin_unlock_irqrestore(&drv->lock, flags); 615 } 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 -----------------------------------------------------------------------------*/ 629 int os_wake_lock_timeout_enable (TI_HANDLE OsContext) 630 { 631 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext; 632 unsigned long flags; 633 int ret = 0; 634 635 if (drv) { 636 spin_lock_irqsave(&drv->lock, flags); 637 ret = drv->wl_packet = 1; 638 spin_unlock_irqrestore(&drv->lock, flags); 639 } 640 return ret; 641 } 642 643 /*----------------------------------------------------------------------------- 644 Routine Name: os_wake_lock 645 646 Routine Description: Called to prevent system from suspend 647 648 Arguments: OsContext - handle to OS context 649 650 Return Value: wake_lock counter 651 -----------------------------------------------------------------------------*/ 652 int os_wake_lock (TI_HANDLE OsContext) 653 { 654 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext; 655 int ret = 0; 656 unsigned long flags; 657 658 if (drv) { 659 spin_lock_irqsave(&drv->lock, flags); 660 #ifdef CONFIG_HAS_WAKELOCK 661 if (!drv->wl_count) 662 wake_lock(&drv->wl_wifi); 663 #endif 664 drv->wl_count++; 665 ret = drv->wl_count; 666 spin_unlock_irqrestore(&drv->lock, flags); 667 } 668 /* printk("%s: %d\n", __func__, ret); */ 669 return ret; 670 } 671 672 /*----------------------------------------------------------------------------- 673 Routine Name: os_wake_unlock 674 675 Routine Description: Called to allow system to suspend 676 677 Arguments: OsContext - handle to OS context 678 679 Return Value: wake_lock counter 680 -----------------------------------------------------------------------------*/ 681 int os_wake_unlock (TI_HANDLE OsContext) 682 { 683 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext; 684 int ret = 0; 685 unsigned long flags; 686 687 if (drv) { 688 spin_lock_irqsave(&drv->lock, flags); 689 if (drv->wl_count) { 690 drv->wl_count--; 691 #ifdef CONFIG_HAS_WAKELOCK 692 if (!drv->wl_count) 693 wake_unlock(&drv->wl_wifi); 694 #endif 695 ret = drv->wl_count; 696 } 697 spin_unlock_irqrestore(&drv->lock, flags); 698 } 699 /* printk("%s: %d\n", __func__, ret); */ 700 return ret; 701 } 702 703 /*----------------------------------------------------------------------------- 704 Routine Name: os_RequestSchedule 705 706 Routine Description: 707 708 Arguments: 709 710 Return Value: TI_OK 711 -----------------------------------------------------------------------------*/ 712 int os_RequestSchedule (TI_HANDLE OsContext) 713 { 714 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)OsContext; 715 716 /* Note: The performance trace below doesn't inclose the schedule 717 * itself because the rescheduling can occur immediately and call 718 * os_RequestSchedule again which will confuse the trace tools */ 719 CL_TRACE_START_L3(); 720 CL_TRACE_END_L3("tiwlan_drv.ko", "OS", "TASK", ""); 721 722 if( !queue_work(drv->tiwlan_wq, &drv->tWork) ) { 723 /* printk("%s: Fail\n",__func__); */ 724 return TI_NOK; 725 } 726 727 return TI_OK; 728 } 729 730 731 /*----------------------------------------------------------------------------- 732 Routine Name: os_SignalObjectCreate 733 734 Routine Description: 735 736 Arguments: 737 738 Return Value: TI_OK 739 -----------------------------------------------------------------------------*/ 740 void *os_SignalObjectCreate (TI_HANDLE OsContext) 741 { 742 struct completion *myPtr; 743 myPtr = os_memoryAlloc(OsContext, sizeof(struct completion)); 744 if (myPtr) 745 init_completion (myPtr); 746 return (myPtr); 747 } 748 749 750 /*----------------------------------------------------------------------------- 751 Routine Name: os_SignalObjectWait 752 753 Routine Description: 754 755 Arguments: 756 757 Return Value: TI_OK 758 -----------------------------------------------------------------------------*/ 759 int os_SignalObjectWait (TI_HANDLE OsContext, void *signalObject) 760 { 761 if (!signalObject) 762 return TI_NOK; 763 if (!wait_for_completion_timeout((struct completion *)signalObject, 764 msecs_to_jiffies(10000))) { 765 printk("tiwlan: 10 sec %s timeout\n", __func__); 766 } 767 return TI_OK; 768 } 769 770 771 /*----------------------------------------------------------------------------- 772 Routine Name: os_SignalObjectSet 773 774 Routine Description: 775 776 Arguments: 777 778 Return Value: TI_OK 779 -----------------------------------------------------------------------------*/ 780 int os_SignalObjectSet (TI_HANDLE OsContext, void *signalObject) 781 { 782 if (!signalObject) 783 return TI_NOK; 784 complete ((struct completion *)signalObject); 785 return TI_OK; 786 } 787 788 789 /*----------------------------------------------------------------------------- 790 Routine Name: os_SignalObjectFree 791 792 Routine Description: 793 794 Arguments: 795 796 Return Value: TI_OK 797 -----------------------------------------------------------------------------*/ 798 int os_SignalObjectFree (TI_HANDLE OsContext, void *signalObject) 799 { 800 if (!signalObject) 801 return TI_NOK; 802 os_memoryFree(OsContext, signalObject, sizeof(struct completion)); 803 return TI_OK; 804 } 805 806 807 /** 808 * \fn os_Trace 809 * \brief Prepare and send trace message to the logger. 810 * 811 * \param OsContext - The OS handle 812 * \param uLevel - Severity level of the trace message 813 * \param uFileId - Source file ID of the trace message 814 * \param uLineNum - Line number of the trace message 815 * \param uParamsNum - Number of parameters in the trace message 816 * \param ... - The trace message parameters 817 * 818 * \return void 819 */ 820 void os_Trace (TI_HANDLE OsContext, TI_UINT32 uLevel, TI_UINT32 uFileId, TI_UINT32 uLineNum, TI_UINT32 uParamsNum, ...) 821 { 822 TI_UINT32 index; 823 TI_UINT32 uParam; 824 TI_UINT32 uMaxParamValue = 0; 825 TI_UINT32 uMsgLen = TRACE_MSG_MIN_LENGTH; 826 TI_UINT8 aMsg[TRACE_MSG_MAX_LENGTH] = {0}; 827 TTraceMsg *pMsgHdr = (TTraceMsg *)&aMsg[0]; 828 TI_UINT8 *pMsgData = &aMsg[0] + sizeof(TTraceMsg); 829 va_list list; 830 831 if (!bRedirectOutputToLogger) 832 { 833 return; 834 } 835 836 if (uParamsNum > TRACE_MSG_MAX_PARAMS) 837 { 838 uParamsNum = TRACE_MSG_MAX_PARAMS; 839 } 840 841 /* sync on the parameters */ 842 va_start(list, uParamsNum); 843 844 /* find the longest parameter */ 845 for (index = 0; index < uParamsNum; index++) 846 { 847 /* get parameter from the stack */ 848 uParam = va_arg (list, TI_UINT32); 849 850 /* save the longest parameter at variable 'uMaxParamValue' */ 851 if (uParam > uMaxParamValue) 852 { 853 uMaxParamValue = uParam; 854 } 855 856 /* 32 bit parameter is the longest possible - get out of the loop */ 857 if (uMaxParamValue > UINT16_MAX_VAL) 858 { 859 break; 860 } 861 } 862 863 /* Set msg length and format according to the biggest parameter value (8/16/32 bits) */ 864 if (uMaxParamValue > UINT16_MAX_VAL) 865 { 866 pMsgHdr->uFormat = TRACE_FORMAT_32_BITS_PARAMS; 867 uMsgLen += uParamsNum * sizeof(TI_UINT32); 868 } 869 else if (uMaxParamValue > UINT8_MAX_VAL) 870 { 871 pMsgHdr->uFormat = TRACE_FORMAT_16_BITS_PARAMS; 872 uMsgLen += uParamsNum * sizeof(TI_UINT16); 873 } 874 else 875 { 876 pMsgHdr->uFormat = TRACE_FORMAT_8_BITS_PARAMS; 877 uMsgLen += uParamsNum; 878 } 879 880 /* Fill all other header information */ 881 pMsgHdr->uLevel = (TI_UINT8)uLevel; 882 pMsgHdr->uParamsNum = (TI_UINT8)uParamsNum; 883 pMsgHdr->uFileId = (TI_UINT16)uFileId; 884 pMsgHdr->uLineNum = (TI_UINT16)uLineNum; 885 886 /* re-sync on the parameters */ 887 va_start(list, uParamsNum); 888 889 /* add the parameters */ 890 for (index = 0; index < uParamsNum; index++) 891 { 892 /* get parameter from the stack */ 893 uParam = va_arg(list, TI_UINT32); 894 895 /* insert the parameter and increment msg pointer */ 896 switch(pMsgHdr->uFormat) 897 { 898 case TRACE_FORMAT_8_BITS_PARAMS: 899 INSERT_BYTE(pMsgData, uParam); 900 break; 901 902 case TRACE_FORMAT_16_BITS_PARAMS: 903 INSERT_2_BYTES(pMsgData, uParam); 904 break; 905 906 case TRACE_FORMAT_32_BITS_PARAMS: 907 INSERT_4_BYTES(pMsgData, uParam); 908 break; 909 910 default: 911 va_end(list); 912 return; 913 } 914 } 915 916 va_end(list); 917 918 /* Send the trace message to the logger */ 919 SendLoggerData(OsContext, aMsg, (TI_UINT16)uMsgLen); 920 } 921 922 /*--------------------------------------------------------------------------------------*/ 923 924 /** 925 * \fn os_SetDrvThreadPriority 926 * \brief Called upon init to set WLAN driver thread priority. 927 * Currently not supported in Linux. 928 * 929 * \param OsContext - The OS handle 930 * \param uWlanDrvThreadPriority - The WLAN driver thread priority 931 * \return 932 */ 933 void os_SetDrvThreadPriority (TI_HANDLE OsContext, TI_UINT32 uWlanDrvThreadPriority) 934 { 935 } 936