blob: 7e215e2da2612ad0d7401d2f0e091f5c33fce6a8 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
2 * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * Airgo Networks, Inc proprietary. All rights reserved
24 * sysEntryFunc.cc - This file has all the system level entry functions
25 * for all the defined threads at system level.
26 * Author: V. K. Kandarpa
27 * Date: 01/16/2002
28 * History:-
29 * Date Modified by Modification Information
30 * --------------------------------------------------------------------------
31 *
32 */
33/* Standard include files */
34
35/* Application Specific include files */
36#include "sirCommon.h"
37#include "aniGlobal.h"
38
39
40#include "limApi.h"
41#include "schApi.h"
42#include "utilsApi.h"
43#include "pmmApi.h"
44
45#include "sysDebug.h"
46#include "sysDef.h"
47#include "sysEntryFunc.h"
48#include "sysStartup.h"
49#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
50#include "halMacSecurityApi.h"
51#endif
52#include "limTrace.h"
53#include "wlan_qct_wda.h"
54
55#ifndef WLAN_FTM_STUB
56tSirRetStatus
57postPTTMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
58#endif
59
60#ifdef VOSS_ENABLED
61#include "vos_types.h"
62#include "vos_packet.h"
63#endif
64
65// ---------------------------------------------------------------------------
66/**
67 * sysInitGlobals
68 *
69 * FUNCTION:
70 * Initializes system level global parameters
71 *
72 * LOGIC:
73 *
74 * ASSUMPTIONS:
75 *
76 * NOTE:
77 *
78 * @param tpAniSirGlobal Sirius software parameter struct pointer
79 * @return None
80 */
81
82tSirRetStatus
83sysInitGlobals(tpAniSirGlobal pMac)
84{
85
86 palZeroMemory(pMac->hHdd, (tANI_U8 *) &pMac->sys, sizeof(pMac->sys));
87
88#if defined(ANI_DEBUG)
89 //FIXME : right now we want the reset to happen even in diag debug build.
90 // later on we need to set this to true.
91 //pMac->sys.debugOnReset = true;
92 pMac->sys.debugOnReset = false;
93#else
94 pMac->sys.debugOnReset = false;
95#endif
96
97 pMac->sys.gSysEnableScanMode = 1;
98 pMac->sys.gSysEnableLinkMonitorMode = 0;
99 pMac->sys.fTestRadar = false;
100 pMac->sys.radarDetected = false;
101 pMac->sys.gSysdropLimPkts = false;
102#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
103 if(eHAL_STATUS_SUCCESS != halGlobalInit(pMac))
104 return eSIR_FAILURE;
105#endif
106 schInitGlobals(pMac);
107
108 return eSIR_SUCCESS;
109}
110
111#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
112
113
114// ---------------------------------------------------------------------------
115/**
116 * sysIsLearnScanModeFrame
117 *
118 * FUNCTION:
119 * Determine whether the received frame was received in learn/scan mode
120 *
121 * LOGIC:
122 *
123 * ASSUMPTIONS:
124 *
125 * NOTE:
126 *
127 * @param pFrame
128 * @return true if frame was received in learn/scan mode
129 * false otherwise
130 */
131
132static inline tANI_U8
133sysIsLearnScanModeFrame(tpHalBufDesc pBd)
134{
135 if( SIR_MAC_BD_TO_SCAN_LEARN(pBd) )
136 return 1;
137 else
138 return 0;
139}
140#endif
141// ---------------------------------------------------------------------------
142/**
143 * sysBbtProcessMessageCore
144 *
145 * FUNCTION:
146 * Process BBT messages
147 *
148 * LOGIC:
149 *
150 * ASSUMPTIONS:
151 *
152 * NOTE:
153 *
154 * @param tpAniSirGlobal A pointer to MAC params instance
155 * @param pMsg message pointer
156 * @param tANI_U32 type
157 * @param tANI_U32 sub type
158 * @return None
159 */
160tSirRetStatus
161sysBbtProcessMessageCore(tpAniSirGlobal pMac, tpSirMsgQ pMsg, tANI_U32 type,
162 tANI_U32 subType)
163{
164 tSirRetStatus ret;
165 void* pBd;
166 tMgmtFrmDropReason dropReason;
167 vos_pkt_t *pVosPkt = (vos_pkt_t *)pMsg->bodyptr;
168 VOS_STATUS vosStatus =
169 WDA_DS_PeekRxPacketInfo( pVosPkt, (v_PVOID_t *)&pBd, VOS_FALSE );
170 pMac->sys.gSysBbtReceived++;
171
172 if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
173 {
174 goto fail;
175 }
176
177 PELOGW(sysLog(pMac, LOGW, FL("Rx Mgmt Frame Subtype: %d\n"), subType);
178 sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOGW, (tANI_U8 *)WDA_GET_RX_MAC_HEADER(pBd), WDA_GET_RX_MPDU_LEN(pBd));
179 sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOGW, WDA_GET_RX_MPDU_DATA(pBd), WDA_GET_RX_PAYLOAD_LEN(pBd));)
180
181 pMac->sys.gSysFrameCount[type][subType]++;
182
183 if(type == SIR_MAC_MGMT_FRAME)
184 {
185
186 if( (dropReason = limIsPktCandidateForDrop(pMac, pBd, subType)) != eMGMT_DROP_NO_DROP)
187 {
188 PELOG1(sysLog(pMac, LOG1, FL("Mgmt Frame %d being dropped, reason: %d\n"), subType, dropReason);)
189 MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_DROP, 0, dropReason);)
190 goto fail;
191 }
192 //Post the message to PE Queue
193 ret = (tSirRetStatus) limPostMsgApi(pMac, pMsg);
194 if (ret != eSIR_SUCCESS)
195 {
196 PELOGE(sysLog(pMac, LOGE, FL("posting to LIM2 failed, ret %d\n"), ret);)
197 goto fail;
198 }
199 pMac->sys.gSysBbtPostedToLim++;
200 }
201#ifdef FEATURE_WLAN_CCX
202 else if (type == SIR_MAC_DATA_FRAME)
203 {
204 PELOGW(sysLog(pMac, LOGW, FL("IAPP Frame...\n")););
205 //Post the message to PE Queue
206 ret = (tSirRetStatus) limPostMsgApi(pMac, pMsg);
207 if (ret != eSIR_SUCCESS)
208 {
209 PELOGE(sysLog(pMac, LOGE, FL("posting to LIM2 failed, ret %d\n"), ret);)
210 goto fail;
211 }
212 pMac->sys.gSysBbtPostedToLim++;
213 }
214#endif
215 else
216 {
217 PELOGE(sysLog(pMac, LOGE, "BBT received Invalid type %d subType %d "
218 "LIM state %X. BD dump is:\n",
219 type, subType, limGetSmeState(pMac));
220 sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOGE,
221 (tANI_U8 *) pBd, WLANHAL_RX_BD_HEADER_SIZE);)
222
223 goto fail;
224 }
225
226 return eSIR_SUCCESS;
227
228fail:
229
230 pMac->sys.gSysBbtDropped++;
231 return eSIR_FAILURE;
232}
233
234
235void sysLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...)
236{
237 // Verify against current log level
238 if ( loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_SYS_MODULE_ID )] )
239 return;
240 else
241 {
242 va_list marker;
243
244 va_start( marker, pString ); /* Initialize variable arguments. */
245
246 logDebug(pMac, SIR_SYS_MODULE_ID, loglevel, pString, marker);
247
248 va_end( marker ); /* Reset variable arguments. */
249 }
250}
251
252
253
254#if defined( ANI_OS_TYPE_WINDOWS )
255// ---------------------------------------------------------------------------
256/**
257 * sysBbtProcessMessage
258 *
259 * FUNCTION:
260 * Process BBT messages
261 *
262 * LOGIC:
263 *
264 * ASSUMPTIONS:
265 *
266 * NOTE:
267 *
268 * @param pBD Buffer descriptor pointer
269 * @return None
270 */
271void sysBbtProcessMessage( tHalHandle hHal, void *pBD )
272{
273 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
274 tpSirMacMgmtHdr mHdr;
275 tSirMsgQ msg;
276
277 //
278 // The MPDU header is now present at a certain "offset" in
279 // the BD and is specified in the BD itself
280 //
281 mHdr = WDA_GET_RX_MAC_HEADER(pBD);
282
283 // Dump received packet
284 /*
285 if(pBD->swBdType != SMAC_SWBD_TYPE_CTLMSG)
286 sysLog( pMac, LOG3,
287 FL( "%s: RX Mesg Type %d, subType %d, MPDU Len %d, RXP Flags 0x%x\n" ),
288 __FUNCTION__,
289 mHdr->fc.type,
290 mHdr->fc.subType,
291 pBD->mpduLength,
292 pBD->rxpFlags );
293 */
294 //sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOGW, SIR_MAC_BD_TO_MPDUDATA(pBD), SIR_MAC_BD_TO_PAYLOAD_LEN(pBD));
295
296 // Forward to MAC via mesg = SIR_BB_XPORT_MGMT_MSG
297 msg.type = SIR_BB_XPORT_MGMT_MSG;
298 msg.bodyptr = pBD;
299 msg.bodyval = 0;
300
301 if( eSIR_SUCCESS != sysBbtProcessMessageCore( pMac,
302 &msg,
303 mHdr->fc.type,
304 mHdr->fc.subType ))
305 {
306 sysLog( pMac, LOGW,
307 FL ( "sysBbtProcessMessageCore failed to process SIR_BB_XPORT_MGMT_MSG\n" ));
308
309 // TODO - Will the caller (HDD) free the received packet?
310 }
311}
312#endif // #if defined( ANI_OS_TYPE_WINDOWS )
313
314#if defined(ANI_OS_TYPE_RTAI_LINUX)
315#ifndef WLAN_FTM_STUB
316#include "pttModuleApi.h"
317#endif // eDRIVER_TYPE_MFG
318
319// ---------------------------------------------------------------------
320/**
321 * sysMmhEntry
322 *
323 * FUNCTION:
324 *
325 * LOGIC:
326 *
327 * ASSUMPTIONS:
328 *
329 * NOTE:
330 *
331 * @param dummy Dummy parameter
332 * @return None
333 */
334void
335sysMmhEntry(tANI_U32 dummy)
336{
337 tSirMbMsg *pMbMsg;
338 tSirMsgQ msg;
339 tpAniSirGlobal pMac;
340
341 pMac = getPMac();
342
343 sysLog(pMac, LOG4, "MMH task started\n");
344
345 while (1)
346 {
347 // Blocks waiting for messages from HDD
348
349 tx_queue_receive(&pMac->sys.gSirTxMsgQ, (void*)&pMbMsg,
350 TX_WAIT_FOREVER);
351 // Compose inter-module message and send it off to the receiver
352 msg.type = sirReadU16N((tANI_U8*)&(pMbMsg->type));
353 msg.bodyptr = pMbMsg;
354 msg.bodyval = 0;
355 sysLog(pMac, LOG4, "<MMH> HDD message received id=0x%x\n", msg.type);
356 if (pMac->sys.abort==1)
357 {
358 if (msg.type==eWNI_SME_STOP_BSS_REQ)
359 {
360 sirStoreU16N((tANI_U8*)(&(pMbMsg->type)), eWNI_SME_STOP_BSS_RSP);
361 pMbMsg->data[0] = 0;
362 halMmhPostMsgApi(pMac, &msg, ePROT);
363 }
364 else
365 {
366 // we should free buffer, but only if it is an skbuff
367 }
368 continue;
369 }
370
371 switch (msg.type & 0xFF00)
372 {
373 case SIR_HAL_MSG_TYPES_BEGIN:
374 if (halPostMsgApi(pMac, &msg) != eSIR_SUCCESS)
375 sysLog(pMac, LOGP, "sysMmhEntry: halPostMsgApi Failed!\n");
376 else
377 {
378 sysLog(pMac, LOG4, "<MMH> Message forwarded to HAL\n");
379 }
380
381 break;
382
383 case SIR_LIM_MSG_TYPES_BEGIN:
384 limPostMsgApi(pMac, &msg);
385 break;
386
387 case SIR_MNT_MSG_TYPES_BEGIN:
388
389 if (halMntPostMsgApi(pMac, &msg) != eSIR_SUCCESS)
390 sysLog(pMac, LOGP, "sysMmhEntry: halMntPostMsgApi Failed!\n");
391 else
392 {
393 sysLog(pMac, LOG4, "<MMH> Message forwarded to MNT type (%X)\n",
394 msg.type);
395 }
396
397 break;
398
399 case SIR_PMM_MSG_TYPES_BEGIN:
400
401 // Shall have its API call here; Once API is added, remove the
402 // following release memory call.
403 break;
404
405 case SIR_CFG_MSG_TYPES_BEGIN:
406
407 if (halMntPostMsgApi(pMac, &msg) != eSIR_SUCCESS)
408 sysLog(pMac, LOGP,
409 "sysMmhEntry: cfg msg: halMntPostMsgApi Failed!\n");
410 else
411 {
412 sysLog(pMac, LOG4,
413 "sysMmhEntry: cfg msg: halMntPostMsgApi!\n");
414 }
415
416 break;
417
418#ifndef WLAN_FTM_STUB
419 case PTT_MSG_TYPES_BEGIN_30: /*PTT_MSG_TYPES_BEGIN:*/
420 case PTT_MSG_TYPES_BEGIN_31:
421 case PTT_MSG_TYPES_BEGIN_32:
422 if (postPTTMsgApi(pMac, &msg) != eSIR_SUCCESS)
423 sysLog(pMac, LOGP,
424 "sysMmhEntry: RD msg: postPTTMsgApi Failed!\n");
425 else
426 {
427 sysLog(pMac, LOG4,
428 "sysMmhEntry: RD msg: postPTTMsgApi!\n");
429 }
430 break;
431#endif
432
433 default:
434 sysLog(pMac, LOGW, "sysMmhEntry Unknown destination \n");
435 // Unknown destination. Just drop it
436 palFreeMemory( pMac->hHdd, (void*)pMbMsg);
437 }
438 }
439
440} /*** sysMmhEntry() ***/
441
442#endif // #if defined(ANI_OS_TYPE_RTAI_LINUX)
443
444#if defined(ANI_OS_TYPE_LINUX) || defined(ANI_OS_TYPE_OSX)
445
446// ---------------------------------------------------------------------------
447/**
448 * sysSchEntry
449 *
450 * FUNCTION:
451 * SCH thread entry function.
452 *
453 * LOGIC:
454 *
455 * ASSUMPTIONS:
456 *
457 * NOTE:
458 *
459 * @param dummy At present there is no need of any entry input. Default=0
460 * @return None
461 */
462void
463sysSchEntry(tANI_U32 i)
464{
465 tpAniSirGlobal pMac;
466 pMac = getPMac();
467 while (1)
468{
469 schProcessMessageQueue(pMac);
470 }
471} // sysSchEntry()
472
473
474// ---------------------------------------------------------------------------
475/**
476 * sysPmmEntry
477 *
478 * FUNCTION:
479 * PMM thread entry function.
480 *
481 * LOGIC:
482 *
483 * ASSUMPTIONS:
484 *
485 * NOTE:
486 *
487 * @param dummy At present there is no need of any entry input. Default=0
488 * @return None
489 */
490void
491sysPmmEntry(tANI_U32 i)
492{
493 tpAniSirGlobal pMac;
494 pMac = getPMac();
495 while (1)
496 {
497 pmmProcessMessageQueue(pMac);
498 }
499} // sysPmmEntry()
500
501
502// ---------------------------------------------------------------------
503/**
504 * sysLimEntry
505 *
506 * FUNCTION:
507 * LIM thread entry point
508 * LOGIC:
509 *
510 * ASSUMPTIONS:
511 *
512 * NOTE:
513 *
514 * @param dummy Dummy parameter
515 * @return None
516 */
517
518void
519sysLimEntry(tANI_U32 dummy)
520{
521 tpAniSirGlobal pMac;
522 pMac = getPMac();
523 limInitialize(pMac);
524
525 while (1)
526 {
527 limProcessMessageQueue(pMac);
528 } // while(1)
529} // limEntry()
530
531
532
533// ---------------------------------------------------------------------
534/**
535 * sysMntEntry
536 *
537 * FUNCTION:
538 * MNT thread entry point
539 * LOGIC:
540 *
541 * ASSUMPTIONS:
542 *
543 * NOTE:
544 *
545 * @param dummy Dummy parameter
546 * @return None
547 */
548
549void
550sysMntEntry(tANI_U32 dummy)
551{
552 tANI_U32 status;
553 tSirMsgQ msg;
554 tpAniSirGlobal pMac;
555 pMac = getPMac();
556 sysLog(pMac, LOG4, "<MNT> MNT task started\n");
557
558#if defined(ANI_OS_TYPE_RTAI_LINUX)
559 tANI_U32 interval;
560 interval = SYS_MNT_INTERVAL * SYS_TICKS_PER_SECOND;
561#endif
562
563 while (1)
564 {
565#if defined(ANI_OS_TYPE_RTAI_LINUX)
566 status = tx_queue_receive(&pMac->sys.gSirMntMsgQ, &msg, interval);
567#else
568 status = tx_queue_receive(&pMac->sys.gSirMntMsgQ, &msg,
569 TX_WAIT_FOREVER);
570#endif
571
572 // this routine only dequeues the message from queue
573 // processing is done by sysMntProcessMsg
574 if (status == TX_SUCCESS)
575 {
576 if (halMntProcessMsgs(pMac, &msg) != eSIR_SUCCESS)
577 {
578 sysLog(pMac, LOGP, "sysMntEntry: halMntProcessMsgs call "
579 "failed!\n");
580 }
581 }
582 }
583} // sysMntEntry()
584
585// ---------------------------------------------------------------------
586/**
587 * sysHalEntry
588 *
589 * FUNCTION:
590 * HAL thread entry point
591 * LOGIC:
592 *
593 * ASSUMPTIONS:
594 *
595 * NOTE:
596 *
597 * @param dummy Dummy parameter
598 * @return None
599 */
600
601void
602sysHalEntry(tANI_U32 dummy)
603{
604 tANI_U32 status;
605 tSirMsgQ msg;
606 tpAniSirGlobal pMac;
607
608 pMac = getPMac();
609 sysLog(pMac, LOG4, "<HAL> HAL task started\n");
610
611 while (1)
612 {
613
614 status = tx_queue_receive(&pMac->sys.gSirHalMsgQ, &msg,
615 TX_WAIT_FOREVER);
616 // this routine only dequeues the message from queue
617 if (status == TX_SUCCESS)
618 {
619 if (halProcessMsg(pMac, &msg) != eSIR_SUCCESS)
620 {
621 sysLog(pMac, LOGP, "sysHalEntry: halProcessMsgQ call failed!\n");
622 }
623 }
624 } // while(1)
625} // sysHalEntry
626
627#ifndef WLAN_FTM_STUB
628#include "pttModuleApi.h"
629// ---------------------------------------------------------------------
630// ---------------------------------------------------------------------
631/**
632 * sysNimPttEntry
633 *
634 * FUNCTION:
635 * NIM PTT thread entry point
636 * LOGIC:
637 *
638 * ASSUMPTIONS:
639 *
640 * NOTE:
641 *
642 * @param dummy Dummy parameter
643 * @return None
644 */
645
646void
647sysNimPttEntry(tANI_U32 dummy)
648{
649 tANI_U32 status;
650 tSirMsgQ msg;
651 tpAniSirGlobal pMac;
652 pMac = getPMac();
653
654 sysLog(pMac, LOGW, "<NIM> PTT task started\n");
655
656 while (1)
657 {
658 status = tx_queue_receive(&pMac->sys.gSirNimRDMsgQ, &msg,
659 TX_WAIT_FOREVER);
660
661 // this routine only dequeues the message from queue
662 if (status == TX_SUCCESS)
663 {
664 pttProcessMsg(pMac, (tPttMsgbuffer *)msg.bodyptr);
665 //TODO: the resonse is now packaged in ((tPttMsgbuffer *)&msg->body)->msgResponse and needs to be sent back to the application
666 }
667 } // while(1)
668} // sysNimPttEntry
669
670// ---------------------------------------------------------------------
671
672// -------------------------------------------------------------
673/**
674 * postPTTMsgApi
675 *
676 * FUNCTION:
677 * Posts NIM messages to gNIM thread
678 *
679 * LOGIC:
680 *
681 * ASSUMPTIONS:pl
682 *
683 *
684 * NOTE:
685 *
686 * @param tpAniSirGlobal MAC parameters structure
687 * @param pMsg pointer with message
688 * @return Success or Failure
689 */
690
691tSirRetStatus
692postPTTMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
693{
694 tSirRetStatus rc = eSIR_SUCCESS;
695 tPttMsgbuffer *pPttMsg;
696 ePttMsgId msgId;
697 uPttMsgs *msgBody;
698 tANI_U8 *pReq = (tANI_U8*) pMsg->bodyptr;
699
700 pPttMsg = (tPttMsgbuffer *)pReq;
701#if (defined(ANI_OS_TYPE_RTAI_LINUX) && defined(ANI_LITTLE_BYTE_ENDIAN))
702 pPttMsg->msgId = sirReadU16N((tANI_U8 *)&(pPttMsg->msgId));
703#endif
704 msgId = (ePttMsgId)(pPttMsg->msgId);
705 msgBody = (uPttMsgs *)&(pPttMsg->msgBody);
706 do
707 {
708#if defined ANI_OS_TYPE_LINUX || defined ANI_OS_TYPE_OSX
709 // Posts message to the queue
710 if (tx_queue_send(&pMac->sys.gSirHalMsgQ, pMsg,
711 TX_NO_WAIT) != TX_SUCCESS)
712 {
713 rc = eSIR_FAILURE;
714 break;
715 }
716#else
717 // For Windows based MAC, instead of posting message to different
718 // queues, we will call the handler routines directly
719
720 //pttProcessMsg(pMac, pMsg);
721 rc = eSIR_SUCCESS;
722#endif
723 }
724 while (0);
725
726 return rc;
727} // postPTTMsgApi()
728
729
730#endif // eDRIVER_TYPE_MFG
731
732#endif // #if defined ANI_OS_TYPE_LINUX || defined ANI_OS_TYPE_OSX
733