blob: 5d29ac40ced2ff0dc9445056a9d9eeeb47396bdc [file] [log] [blame]
Abhishek Singh00b71972016-01-07 10:51:04 +05301/*
Jeff Johnson0fe596e2017-09-19 08:36:48 -07002 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
Abhishek Singh00b71972016-01-07 10:51:04 +05303 *
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 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*
29 * This file limRMC.c contains the code
30 * for processing RMC messages
31 *
32 */
33#include "wniApi.h"
34#include "wniCfg.h"
35#include "cfgApi.h"
36#include "sirApi.h"
37#include "schApi.h"
38#include "utilsApi.h"
39#include "limUtils.h"
40#include "limTimerUtils.h"
41#include "limSendMessages.h"
42#include "limSendMessages.h"
43#include "limSession.h"
44#include "limSessionUtils.h"
45#include "wlan_qct_wda.h"
46#include "wlan_qct_tli.h"
47#include "limRMC.h"
48
49#ifdef WLAN_FEATURE_RMC
50
51static tANI_U8
52__rmcGroupHashFunction(tSirMacAddr transmitter)
53{
54 tANI_U16 hash;
55
56 /*
57 * Generate a hash using transmitter address
58 */
59 hash = transmitter[0] + transmitter[1] + transmitter[2] +
60 transmitter[3] + transmitter[4] + transmitter[5];
61
62 return hash & (RMC_MCAST_GROUPS_HASH_SIZE - 1);
63}
64
65
66static tLimRmcGroupContext *
67__rmcGroupLookupHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter)
68{
69 tANI_U8 index;
70 tLimRmcGroupContext *entry;
71
72 index = __rmcGroupHashFunction(transmitter);
73
74 /* Pick the correct hash table based on role */
75 entry = pMac->rmcContext.rmcGroupRxHashTable[index];
76
77 PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Lookup:[%d] transmitter "
78 MAC_ADDRESS_STR ), index,
79 MAC_ADDR_ARRAY(transmitter));)
80 while (entry)
81 {
82 if (vos_mem_compare(transmitter, entry->transmitter,
83 sizeof(v_MACADDR_t)))
84 {
85 return entry;
86 }
87
88 entry = entry->next;
89 }
90
91 return NULL;
92}
93
94static tLimRmcGroupContext *
95__rmcGroupInsertHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter)
96{
97 tANI_U8 index;
98 tLimRmcGroupContext *entry;
99 tLimRmcGroupContext **head;
100
101 index = __rmcGroupHashFunction(transmitter);
102
103 PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Insert:[%d] group " MAC_ADDRESS_STR
104 " transmitter " MAC_ADDRESS_STR), index,
105 MAC_ADDR_ARRAY(mcastGroupAddr),
106 MAC_ADDR_ARRAY(transmitter));)
107
108 head = &pMac->rmcContext.rmcGroupRxHashTable[index];
109
110 entry = __rmcGroupLookupHashEntry(pMac, transmitter);
111
112 if (entry)
113 {
114 /* If the entry exists, return it at the end */
115 PELOGE(limLog(pMac, LOGE, FL("RMC: Hash Insert:"
116 MAC_ADDRESS_STR "exists"), MAC_ADDR_ARRAY(transmitter));)
117 }
118 else
119 {
120 entry = (tLimRmcGroupContext *)vos_mem_malloc(sizeof(*entry));
121
Jeff Johnson0fe596e2017-09-19 08:36:48 -0700122 PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Insert:new entry %pK"), entry);)
Abhishek Singh00b71972016-01-07 10:51:04 +0530123
124 if (entry)
125 {
126 vos_mem_copy(entry->transmitter, transmitter, sizeof(tSirMacAddr));
127 entry->isRuler = eRMC_IS_NOT_A_RULER;
128
129 /* chain this entry */
130 entry->next = *head;
131 *head = entry;
132 }
133 else
134 {
135 PELOGE(limLog(pMac, LOGE, FL("RMC: Hash Insert:" MAC_ADDRESS_STR
136 " alloc failed"), MAC_ADDR_ARRAY(transmitter));)
137 }
138 }
139
140 return entry;
141}
142
143/**
144 * __rmcGroupDeleteHashEntry()
145 *
146 *FUNCTION:
147 * This function is called to delete a RMC group entry
148 *
149 *LOGIC:
150 *
151 *ASSUMPTIONS:
152 * Should be called with lkRmcLock held.
153 *
154 *NOTE:
155 * Make sure (for the transmitter role) that the entry is
156 * not in the Pending Response queue.
157 *
158 * @param transmitter - address of multicast transmitter
159 *
160 * @return status
161 */
162static tSirRetStatus
163__rmcGroupDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter)
164{
165 tSirRetStatus status = eSIR_FAILURE;
166 tANI_U8 index;
167 tLimRmcGroupContext *entry, *prev, **head;
168
169 index = __rmcGroupHashFunction(transmitter);
170
171 head = &pMac->rmcContext.rmcGroupRxHashTable[index];
172 entry = *head;
173 prev = NULL;
174
175 while (entry)
176 {
177 if (vos_mem_compare(transmitter, entry->transmitter,
178 sizeof(v_MACADDR_t)))
179 {
180 if (*head == entry)
181 {
182 *head = entry->next;
183 }
184 else
185 {
186 prev->next = entry->next;
187 }
188
Jeff Johnson0fe596e2017-09-19 08:36:48 -0700189 PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Delete: entry %pK "
Abhishek Singh00b71972016-01-07 10:51:04 +0530190 " transmitter " MAC_ADDRESS_STR), entry
191 MAC_ADDR_ARRAY(transmitter));)
192
193 /* free the group entry */
194 vos_mem_free(entry);
195
196 status = eSIR_SUCCESS;
197 break;
198 }
199
200 prev = entry;
201 entry = entry->next;
202 }
203
204 return status;
205}
206
207static void
208__rmcGroupDeleteAllEntries(tpAniSirGlobal pMac)
209{
210 tLimRmcGroupContext *entry, **head;
211 int index;
212
213 PELOG1(limLog(pMac, LOG1, FL("RMC: Hash_Delete_All"),);)
214
215 for (index = 0; index < RMC_MCAST_GROUPS_HASH_SIZE; index++)
216 {
217 head = &pMac->rmcContext.rmcGroupRxHashTable[index];
218
219 entry = *head;
220
221 while (entry)
222 {
223 *head = entry->next;
224 /* free the group entry */
225 vos_mem_free(entry);
226 entry = *head;
227 }
228 }
229}
230
231static void
232__limPostMsgRulerReq ( tpAniSirGlobal pMac,
233 tANI_U8 cmd,
234 tSirMacAddr mcastTransmitter)
235{
236 tSirMsgQ msg;
237 tSirRmcRulerReq *pRulerReq;
238
239 pRulerReq = vos_mem_malloc(sizeof(*pRulerReq));
240 if (NULL == pRulerReq)
241 {
242 limLog(pMac, LOGE, FL("AllocateMemory() failed"));
243 return;
244 }
245
246 pRulerReq->cmd = cmd;
247
248 vos_mem_copy(pRulerReq->mcastTransmitter, mcastTransmitter,
249 sizeof(tSirMacAddr));
250
251 /* Initialize black list */
252 vos_mem_zero(pRulerReq->blacklist, sizeof(pRulerReq->blacklist));
253
254 if (eRMC_SUGGEST_RULER_CMD == cmd)
255 {
256 /* TODO - Set the black list. */
257 }
258
259 msg.type = WDA_RMC_RULER_REQ;
260 msg.bodyptr = pRulerReq;
261 msg.bodyval = 0;
262
263 MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));
264 if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
265 {
266 vos_mem_free(pRulerReq);
267 limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed"));
268 }
269
270 return;
271}
272
273static void
274__limPostMsgUpdateInd ( tpAniSirGlobal pMac,
275 tANI_U8 indication,
276 tANI_U8 role,
277 tSirMacAddr mcastTransmitter,
278 tSirMacAddr mcastRuler)
279{
280 tSirMsgQ msg;
281 tSirRmcUpdateInd *pUpdateInd;
282
283 pUpdateInd = vos_mem_malloc(sizeof(*pUpdateInd));
284 if ( NULL == pUpdateInd )
285 {
286 limLog(pMac, LOGE, FL("AllocateMemory() failed"));
287 return;
288 }
289
290 vos_mem_zero(pUpdateInd, sizeof(*pUpdateInd));
291
292 pUpdateInd->indication = indication;
293 pUpdateInd->role = role;
294
295 vos_mem_copy(pUpdateInd->mcastTransmitter,
296 mcastTransmitter, sizeof(tSirMacAddr));
297
298 vos_mem_copy(pUpdateInd->mcastRuler,
299 mcastRuler, sizeof(tSirMacAddr));
300
301 msg.type = WDA_RMC_UPDATE_IND;
302 msg.bodyptr = pUpdateInd;
303 msg.bodyval = 0;
304
305 MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type));
306 if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
307 {
308 vos_mem_free(pUpdateInd);
309 limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed"));
310 }
311
312 return;
313}
314
315static char *
316__limRulerMessageToString(eRmcMessageType msgType)
317{
318 switch (msgType)
319 {
320 default:
321 return "Invalid";
322 case eLIM_RMC_ENABLE_REQ:
323 return "RMC_ENABLE_REQ";
324 case eLIM_RMC_DISABLE_REQ:
325 return "RMC_DISABLE_REQ";
326 case eLIM_RMC_RULER_SELECT_RESP:
327 return "RMC_RULER_SELECT_RESP";
328 case eLIM_RMC_RULER_PICK_NEW:
329 return "RMC_RULER_PICK_NEW";
330 case eLIM_RMC_OTA_RULER_INFORM_ACK:
331 return "RMC_OTA_RULER_INFORM_ACK";
332 case eLIM_RMC_OTA_RULER_INFORM_SELECTED:
333 return "RMC_OTA_RULER_INFORM_SELECTED";
334 case eLIM_RMC_BECOME_RULER_RESP:
335 return "RMC_BECOME_RULER_RESP";
336 case eLIM_RMC_OTA_RULER_INFORM_CANCELLED:
337 return "RMC_OTA_RULER_INFORM_CANCELLED";
338 }
339}
340
341static char *
342__limRulerStateToString(eRmcRulerState state)
343{
344 switch (state)
345 {
346 default:
347 return "Invalid";
348 case eRMC_IS_NOT_A_RULER:
349 return "Device Not a Ruler";
350 case eRMC_RULER_PENDING:
351 return "Pending firmware resp";
352 case eRMC_IS_A_RULER:
353 return "Device is Ruler";
354 }
355}
356
357static char *
358__limMcastTxStateToString(eRmcMcastTxState state)
359{
360 switch (state)
361 {
362 default:
363 return "Invalid";
364 case eRMC_RULER_NOT_SELECTED:
365 return "Not Selected";
366 case eRMC_RULER_ENABLE_REQUESTED:
367 return "Enable Requested";
368 case eRMC_RULER_OTA_REQUEST_SENT:
369 return "OTA Request Sent";
370 case eRMC_RULER_ACTIVE:
371 return "Active";
372 }
373}
374
375/**
376 * __rmcRulerSelectTimerHandler()
377 *
378 *FUNCTION:
379 * This function is called upon timer expiry.
380 *
381 *
382 *ASSUMPTIONS:
383 * NA
384 *
385 *NOTE:
386 * Only one entry is processed for every invocation if this routine.
387 * This allows us to use a single timer and makes sure we do not
388 * timeout a request too early.
389 *
390 * @param param - Message corresponding to the timer that expired
391 *
392 * @return None
393 */
394
395void
396__rmcRulerSelectTimerHandler(void *pMacGlobal, tANI_U32 param)
397{
398 tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal;
399 tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 };
400 tSirRetStatus status;
401 tSirRMCInfo RMC;
402 tpPESession psessionEntry;
403 tANI_U32 cfgValue;
404
405 /*
406 * This API relies on a single active IBSS session.
407 */
408 psessionEntry = limIsIBSSSessionActive(pMac);
409 if (NULL == psessionEntry)
410 {
411 PELOGE(limLog(pMac, LOGE,
412 FL("RMC:__rmcRulerSelectTimerHandler:No active IBSS"));)
413 return;
414 }
415
416 if (wlan_cfgGetInt(pMac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
417 &cfgValue) != eSIR_SUCCESS)
418 {
419 /**
420 * Could not get Action Period Frequency value
421 * from CFG. Log error.
422 */
423 limLog(pMac, LOGE, FL("could not retrieve ActionPeriodFrequency"));
424 }
425
426 cfgValue = SYS_MS_TO_TICKS(cfgValue);
427
428 if (pMac->rmcContext.rmcTimerValInTicks != cfgValue)
429 {
430 limLog(pMac, LOG1, FL("RMC RulerSelect timer value changed"));
431 if (tx_timer_change(&pMac->rmcContext.gRmcRulerSelectTimer,
432 cfgValue, 0) != TX_SUCCESS)
433 {
434 limLog(pMac, LOGE,
435 FL("Unable to change RulerSelect Timer val"));
436 }
437 pMac->rmcContext.rmcTimerValInTicks = cfgValue;
438 }
439
440 /*
441 * If we are in the scanning state then we need to return
442 * from this function without any further processing
443 */
444 if (eLIM_HAL_SCANNING_STATE == pMac->lim.gLimHalScanState)
445 {
446 limLog(pMac, LOG1, FL("In scanning state, can't send action frm"));
447 if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer) !=
448 TX_SUCCESS)
449 {
450 limLog(pMac, LOGE, FL("In scanning state, "
451 "couldn't activate RMC RulerSelect timer"));
452 }
453 return;
454 }
455
456 if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
457 {
458 limLog(pMac, LOGE,
459 FL("__rmcRulerSelectTimerHandler lock acquire failed"));
460 if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= TX_SUCCESS)
461 {
462 limLog(pMac, LOGE, FL("could not activate RMC RulerSelect timer"));
463 }
464 return;
465 }
466
467 vos_mem_copy(&RMC.mcastRuler, &pMac->rmcContext.ruler,
468 sizeof(tSirMacAddr));
469
470 if (VOS_FALSE == vos_mem_compare(&zeroMacAddr,
471 &pMac->rmcContext.ruler, sizeof(tSirMacAddr)))
472 {
473 limLog(pMac, LOG1,
474 FL("RMC Periodic Ruler_Select Ruler " MAC_ADDRESS_STR),
475 MAC_ADDR_ARRAY(pMac->rmcContext.ruler));
476 /*
477 * Re-arm timer
478 */
479 if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!=
480 TX_SUCCESS)
481 {
482 limLog(pMac, LOGE, FL("could not activate RMC Response timer"));
483 }
484
485 if (!VOS_IS_STATUS_SUCCESS
486 (vos_lock_release(&pMac->rmcContext.lkRmcLock)))
487 {
488 limLog(pMac, LOGE,
489 FL("RMC: __rmcRulerSelectTimerHandler lock release failed"));
490 }
491 }
492 else
493 {
494 limLog(pMac, LOGE,
495 FL("RMC Deactivating timer because no ruler was selected"));
496
497 if (!VOS_IS_STATUS_SUCCESS
498 (vos_lock_release(&pMac->rmcContext.lkRmcLock)))
499 {
500 limLog(pMac, LOGE,
501 FL("RMC: __rmcRulerSelectTimerHandler lock release failed"));
502 }
503
504 return;
505 }
506
507 RMC.dialogToken = 0;
508 RMC.action = SIR_MAC_RMC_RULER_INFORM_SELECTED;
509
510 status = limSendRMCActionFrame(pMac,
511 SIR_MAC_RMC_MCAST_ADDRESS,
512 &RMC,
513 psessionEntry);
514
515 if (eSIR_FAILURE == status)
516 {
517 PELOGE(limLog(pMac, LOGE,
518 FL("RMC:__rmcRulerSelectTimerHandler Action frame send failed"));)
519 }
520
521 return;
522}
523
524static void
525__limProcessRMCEnableRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
526{
527 tSirSetRMCReq *setRmcReq = (tSirSetRMCReq *)pMsgBuf;
528 tpPESession psessionEntry;
529
530 if (!setRmcReq)
531 {
532 PELOGE(limLog(pMac, LOGE, FL("RMC: Enable:NULL message") );)
533 return;
534 }
535
536 pMac->rmcContext.rmcEnabled = TRUE;
537
538 /*
539 * This API relies on a single active IBSS session.
540 */
541 psessionEntry = limIsIBSSSessionActive(pMac);
542 if (NULL == psessionEntry)
543 {
544 PELOGE(limLog(pMac, LOGE, FL("RMC:Enable RMC request no active IBSS"));)
545 pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
546 return;
547 }
548
549 /* Send RULER_REQ to f/w */
550 __limPostMsgRulerReq(pMac, eRMC_SUGGEST_RULER_CMD,
551 setRmcReq->mcastTransmitter);
552
553 pMac->rmcContext.state = eRMC_RULER_ENABLE_REQUESTED;
554}
555
556static void
557__limProcessRMCDisableRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
558{
559 tpPESession psessionEntry;
560 tSirRMCInfo RMC;
561 tSirSetRMCReq *setRmcReq = (tSirSetRMCReq *)pMsgBuf;
562 tSirRetStatus status;
563 v_PVOID_t pvosGCtx;
564 VOS_STATUS vos_status;
565 v_MACADDR_t vosMcastTransmitter;
566
567 pMac->rmcContext.rmcEnabled = FALSE;
568
569 /*
570 * This API relies on a single active IBSS session.
571 */
572 psessionEntry = limIsIBSSSessionActive(pMac);
573 if (NULL == psessionEntry)
574 {
575 PELOGE(limLog(pMac, LOGE, FL("RMC: Disable:No active IBSS"));)
576 return;
577 }
578
579 if (!setRmcReq)
580 {
581 PELOGE(limLog(pMac, LOGE, FL("RMC: Disable:NULL message") );)
582 return;
583 }
584
585 /* Cancel pending timer */
586 tx_timer_deactivate(&pMac->rmcContext.gRmcRulerSelectTimer);
587
588 vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
589 vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
590 vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
591 vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
592 vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
593 vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
594
595 pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
596 vos_status = WLANTL_DisableRMC(pvosGCtx, &vosMcastTransmitter);
597
598 if (VOS_STATUS_SUCCESS != vos_status)
599 {
600 PELOGE(limLog(pMac, LOGE, FL("RMC:Disable: TL disable failed"));)
601 }
602
603 if (pMac->rmcContext.state == eRMC_RULER_ACTIVE)
604 {
605 RMC.dialogToken = 0;
606 RMC.action = SIR_MAC_RMC_RULER_INFORM_CANCELLED;
607 vos_mem_copy(&RMC.mcastRuler, &pMac->rmcContext.ruler, sizeof(tSirMacAddr));
608
609 status = limSendRMCActionFrame(pMac, pMac->rmcContext.ruler,
610 &RMC, psessionEntry);
611 if (eSIR_FAILURE == status)
612 {
613 PELOGE(limLog(pMac, LOGE, FL("RMC:Disable: Action frame send failed"));)
614 }
615
616 pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
617 }
618
619 __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED, eRMC_TRANSMITTER_ROLE,
620 setRmcReq->mcastTransmitter, pMac->rmcContext.ruler);
621
622 vos_mem_zero(pMac->rmcContext.ruler, sizeof(tSirMacAddr));
623
624}
625
626static void
627__limProcessRMCRulerSelectResponse(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
628{
629 tSirRmcRulerSelectInd *pRmcRulerSelectInd;
630 tpPESession psessionEntry;
631 tSirRetStatus status;
632 v_PVOID_t pvosGCtx;
633 VOS_STATUS vos_status;
634 v_MACADDR_t vosMcastTransmitter;
635 tSirRMCInfo RMC;
636
637 if (NULL == pMsgBuf)
638 {
639 PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Select_Resp:NULL message"));)
640 return;
641 }
642
643 /*
644 * This API relies on a single active IBSS session.
645 */
646 psessionEntry = limIsIBSSSessionActive(pMac);
647 if (NULL == psessionEntry)
648 {
649 PELOGE(limLog(pMac, LOGE, FL("RMC:Ruler_Select_Resp:No active IBSS"));)
650 pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
651 return;
652 }
653
654 pRmcRulerSelectInd = (tSirRmcRulerSelectInd *)pMsgBuf;
655
656 if (pMac->rmcContext.state != eRMC_RULER_ENABLE_REQUESTED)
657 {
658 PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Select_Resp:Bad state %s"),
659 __limMcastTxStateToString(pMac->rmcContext.state) );)
660 return;
661 }
662
663 if (pRmcRulerSelectInd->status)
664 {
665 PELOGE(limLog(pMac, LOGE, FL("RMC:Ruler_Select_Resp:FW Status %d"),
666 pRmcRulerSelectInd->status);)
667 pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
668 return;
669 }
670
671 if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
672 {
673 limLog(pMac, LOGE, FL("RMC:Ruler_Select_Resp:lock acquire failed"));
674 pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
675 return;
676 }
677
678 vos_mem_copy(&pMac->rmcContext.ruler, &pRmcRulerSelectInd->ruler[0],
679 sizeof(tSirMacAddr));
680
681 if (!VOS_IS_STATUS_SUCCESS
682 (vos_lock_release(&pMac->rmcContext.lkRmcLock)))
683 {
684 limLog(pMac, LOGE, FL("RMC: Ruler_Select_Resp: lock release failed"));
685 }
686
687 RMC.dialogToken = 0;
688 RMC.action = SIR_MAC_RMC_RULER_INFORM_SELECTED;
689 vos_mem_copy(&RMC.mcastRuler, &pRmcRulerSelectInd->ruler[0],
690 sizeof(tSirMacAddr));
691
692 PELOG1(limLog(pMac, LOG1, FL("RMC: Ruler_Select :ruler " MAC_ADDRESS_STR),
693 MAC_ADDR_ARRAY(pRmcRulerSelectInd->ruler[0]));)
694
695 status = limSendRMCActionFrame(pMac,
696 SIR_MAC_RMC_MCAST_ADDRESS,
697 &RMC,
698 psessionEntry);
699
700 if (eSIR_FAILURE == status)
701 {
702 PELOGE(limLog(pMac, LOGE,
703 FL("RMC: Ruler_Select_Resp: Action send failed"));)
704 }
705
706 __limPostMsgUpdateInd(pMac, eRMC_RULER_ACCEPTED, eRMC_TRANSMITTER_ROLE,
707 psessionEntry->selfMacAddr, pMac->rmcContext.ruler);
708
709 vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
710 vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
711 vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
712 vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
713 vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
714 vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
715
716 /* Enable TL */
717 pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
718 vos_status = WLANTL_EnableRMC(pvosGCtx, &vosMcastTransmitter);
719
720 pMac->rmcContext.state = eRMC_RULER_ACTIVE;
721
722 if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= TX_SUCCESS)
723 {
724 limLog(pMac, LOGE,
725 FL("Ruler_Select_Resp:Activate RMC Response timer failed"));
726 }
727}
728
729static void
730__limProcessRMCRulerPickNew(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
731{
732 tSirRmcUpdateInd *pRmcUpdateInd;
733 tpPESession psessionEntry;
734 tSirRetStatus status;
735 tSirRMCInfo RMC;
736 v_PVOID_t pvosGCtx;
737 VOS_STATUS vos_status;
738 v_MACADDR_t vosMcastTransmitter;
739 tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 };
740
741 if (NULL == pMsgBuf)
742 {
743 PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Pick_New:NULL message"));)
744 return;
745 }
746
747 /*
748 * This API relies on a single active IBSS session.
749 */
750 psessionEntry = limIsIBSSSessionActive(pMac);
751 if (NULL == psessionEntry)
752 {
753 PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Pick_New:No active IBSS"));)
754 return;
755 }
756
757 pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac);
758
759 pRmcUpdateInd = (tSirRmcUpdateInd *)pMsgBuf;
760
761 if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
762 {
763 limLog(pMac, LOGE, FL("RMC:Ruler_Pick_New:lock acquire failed"));
764 return;
765 }
766
767
768 /* Fill out Action frame parameters */
769 RMC.dialogToken = 0;
770
771 if (VOS_FALSE == vos_mem_compare(&zeroMacAddr,
772 &pRmcUpdateInd->mcastRuler,
773 sizeof(tSirMacAddr)))
774 {
775
776 vos_mem_copy(&RMC.mcastRuler, &pRmcUpdateInd->mcastRuler,
777 sizeof(tSirMacAddr));
778
779 RMC.action = SIR_MAC_RMC_RULER_INFORM_CANCELLED;
780 status = limSendRMCActionFrame(pMac,
781 pRmcUpdateInd->mcastRuler,
782 &RMC, psessionEntry);
783 if (eSIR_FAILURE == status)
784 {
785 PELOGE(limLog(pMac, LOGE,
786 FL("RMC:Ruler_Pick_New: Inform_Cancel Action send failed"));)
787 goto done;
788 }
789
790 vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
791 vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
792 vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
793 vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
794 vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
795 vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
796
797 vos_status = WLANTL_DisableRMC(pvosGCtx, &vosMcastTransmitter);
798
799 if (VOS_STATUS_SUCCESS != vos_status)
800 {
801 PELOGE(limLog(pMac, LOGE,
802 FL("RMC:Ruler_Pick_New: TL disable failed"));)
803 }
804 }
805
806 vos_mem_copy(pMac->rmcContext.ruler, pRmcUpdateInd->ruler[0],
807 sizeof(tSirMacAddr));
808
809 pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED;
810
811 if (VOS_TRUE == vos_mem_compare(&zeroMacAddr,
812 pMac->rmcContext.ruler,
813 sizeof(tSirMacAddr)))
814 {
815 PELOGE(limLog(pMac, LOGE,
816 FL("RMC:Ruler_Pick_New: No candidate rulers available"));)
817 goto done;
818 }
819
820
821 RMC.action = SIR_MAC_RMC_RULER_INFORM_SELECTED;
822 vos_mem_copy(&RMC.mcastRuler, &pMac->rmcContext.ruler,
823 sizeof(tSirMacAddr));
824 status = limSendRMCActionFrame(pMac, SIR_MAC_RMC_MCAST_ADDRESS,
825 &RMC, psessionEntry);
826 if (eSIR_FAILURE == status)
827 {
828 PELOGE(limLog(pMac, LOGE,
829 FL("RMC:Ruler_Pick_New: Inform_Selected Action send failed"));)
830 goto done;
831 }
832
833 __limPostMsgUpdateInd(pMac, eRMC_RULER_ACCEPTED, eRMC_TRANSMITTER_ROLE,
834 psessionEntry->selfMacAddr, pMac->rmcContext.ruler);
835
836 vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0];
837 vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1];
838 vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2];
839 vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3];
840 vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4];
841 vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5];
842
843 /* Enable TL */
844 vos_status = WLANTL_EnableRMC(pvosGCtx, &vosMcastTransmitter);
845
846 if (VOS_STATUS_SUCCESS != vos_status)
847 {
848 PELOGE(limLog(pMac, LOGE,
849 FL("RMC:Ruler_Pick_New: TL enable failed"));)
850 goto done;
851 }
852
853 pMac->rmcContext.state = eRMC_RULER_ACTIVE;
854
855 if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= TX_SUCCESS)
856 {
857 limLog(pMac, LOGE,
858 FL("Ruler_Pick_New:Activate RMC Response timer failed"));
859 }
860
861done:
862 if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
863 {
864 limLog(pMac, LOGE,
865 FL("RMC: Ruler_Pick_New: lock release failed"));
866 }
867}
868
869static void
870__limProcessRMCRulerInformSelected(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
871{
872 tpSirMacMgmtHdr pHdr;
873 tANI_U8 *pFrameData;
874 tANI_U32 frameLen;
875 tLimRmcGroupContext *entry;
876 tpPESession psessionEntry;
877 tSirRetStatus status;
878
879 if (!pMsgBuf)
880 {
881 PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform:NULL msg"));)
882 return;
883 }
884
885 /*
886 * This API relies on a single active IBSS session.
887 */
888 psessionEntry = limIsIBSSSessionActive(pMac);
889 if (NULL == psessionEntry)
890 {
891 PELOGE(limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:No active IBSS"));)
892 return;
893 }
894
895 /*
896 * Get the frame header
897 */
898 pHdr = WDA_GET_RX_MAC_HEADER((tANI_U8 *)pMsgBuf);
899
900 frameLen = WDA_GET_RX_PAYLOAD_LEN((tANI_U8 *)pMsgBuf);
901 if (frameLen < sizeof(tSirMacIbssExtNetworkFrameHdr))
902 {
903 PELOGE(limLog(pMac, LOGE,
904 FL("RMC: Ruler_Inform:Bad length %d "), frameLen);)
905 return;
906 }
907
908 pFrameData = WDA_GET_RX_MPDU_DATA((tANI_U8 *)pMsgBuf) +
909 sizeof(tSirMacIbssExtNetworkFrameHdr);
910
911 if (!pFrameData)
912 {
913 PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform:NULL data"));)
914 return;
915 }
916
917 if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
918 {
919 limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:lock acquire failed"));
920 return;
921 }
922
923 /*
924 * Check if this transmitter exists in our database.
925 */
926 entry = __rmcGroupLookupHashEntry(pMac, pHdr->sa);
927
928 if (VOS_FALSE == vos_mem_compare(pFrameData, psessionEntry->selfMacAddr,
929 sizeof(tSirMacAddr)))
930 {
931 if (entry)
932 {
933 PELOG1(limLog(pMac, LOG1,
934 FL("RMC: Ruler_Inform: Ruler Cancelled"));)
935
936 __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED,
937 eRMC_RULER_ROLE, pHdr->sa, psessionEntry->selfMacAddr);
938
939 /*
940 * Delete hash entry for this Group address.
941 */
942 status = __rmcGroupDeleteHashEntry(pMac, pHdr->sa);
943 if (eSIR_FAILURE == status)
944 {
945 PELOGE(limLog(pMac, LOGE,
946 FL("RMC: Ruler_Inform:hash delete failed"));)
947 }
948 }
949 }
950 else
951 {
952 if (NULL == entry)
953 {
954 /* Add the transmitter address to the hash */
955 entry = __rmcGroupInsertHashEntry(pMac, pHdr->sa);
956 if (entry)
957 {
958 if (entry->isRuler != eRMC_RULER_PENDING)
959 {
960 __limPostMsgRulerReq(pMac, eRMC_BECOME_RULER_CMD,
961 pHdr->sa);
962 entry->isRuler = eRMC_RULER_PENDING;
963 }
964 }
965 else
966 {
967 PELOGE(limLog(pMac, LOGE,
968 FL("RMC: Ruler_Inform:Hash insert failed"));)
969 }
970
971 }
972 }
973
974 if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
975 {
976 limLog(pMac, LOGE,
977 FL("RMC: Ruler_Inform: lock release failed"));
978 }
979
980}
981
982static void
983__limProcessRMCBecomeRulerResp(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
984{
985 tSirRmcBecomeRulerInd *pRmcBecomeRulerInd;
986 tLimRmcGroupContext *entry;
987 tSirRetStatus status = eSIR_SUCCESS;
988
989 if (NULL == pMsgBuf)
990 {
991 PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Ruler_Resp:NULL message"));)
992 return;
993 }
994
995 pRmcBecomeRulerInd = (tSirRmcBecomeRulerInd *)pMsgBuf;
996
997 if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
998 {
999 limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:lock acquire failed"));
1000 return;
1001 }
1002
1003 /*
1004 * Find the entry for this Group Address.
1005 */
1006 entry = __rmcGroupLookupHashEntry(pMac,
1007 pRmcBecomeRulerInd->mcastTransmitter);
1008 if (NULL == entry)
1009 {
1010 PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Ruler_Resp: No entry"));)
1011 goto done;
1012 }
1013
1014 if (pRmcBecomeRulerInd->status)
1015 {
1016 PELOGE(limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:FW Status %d"),
1017 pRmcBecomeRulerInd->status);)
1018 status = eSIR_FAILURE;
1019 goto done;
1020 }
1021
1022 if (entry->isRuler != eRMC_RULER_PENDING)
1023 {
1024 PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Ruler_Resp:Bad state: %s"),
1025 __limRulerStateToString(entry->isRuler) );)
1026 status = eSIR_FAILURE;
1027 goto done;
1028 }
1029
1030 entry->isRuler = eRMC_IS_A_RULER;
1031
1032done:
1033 if (eSIR_FAILURE == status)
1034 {
1035 status = __rmcGroupDeleteHashEntry(pMac,
1036 pRmcBecomeRulerInd->mcastTransmitter);
1037 if (eSIR_FAILURE == status)
1038 {
1039 PELOGE(limLog(pMac, LOGE,
1040 FL("RMC: Become_Ruler_Resp:hash delete failed"));)
1041 }
1042 }
1043
1044 if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
1045 {
1046 limLog(pMac, LOGE,
1047 FL("RMC: Become_Ruler_Resp: lock release failed"));
1048 }
1049
1050 return;
1051}
1052
1053static void
1054__limProcessRMCRulerInformCancelled(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
1055{
1056 tpSirMacMgmtHdr pHdr;
1057 tANI_U8 *pFrameData;
1058 tANI_U32 frameLen;
1059 tSirRetStatus status;
1060 tLimRmcGroupContext *entry;
1061 tpPESession psessionEntry;
1062
1063 if (!pMsgBuf)
1064 {
1065 PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform_Cancel:NULL msg"));)
1066 return;
1067 }
1068
1069 /*
1070 * This API relies on a single active IBSS session.
1071 */
1072 psessionEntry = limIsIBSSSessionActive(pMac);
1073 if (NULL == psessionEntry)
1074 {
1075 PELOGE(limLog(pMac, LOGE,
1076 FL("RMC:Ruler_Inform_Cancel:No active IBSS"));)
1077 return;
1078 }
1079
1080 pHdr = WDA_GET_RX_MAC_HEADER((tANI_U8 *)pMsgBuf);
1081
1082 frameLen = WDA_GET_RX_PAYLOAD_LEN((tANI_U8 *)pMsgBuf);
1083 if (frameLen < sizeof(tSirMacIbssExtNetworkFrameHdr))
1084 {
1085 PELOGE(limLog(pMac, LOGE,
1086 FL("RMC: Ruler_Inform:Bad length %d "), frameLen);)
1087 return;
1088 }
1089
1090 pFrameData = WDA_GET_RX_MPDU_DATA((tANI_U8 *)pMsgBuf) +
1091 sizeof(tSirMacIbssExtNetworkFrameHdr);
1092
1093 if (!pFrameData)
1094 {
1095 PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform_Cancel:NULL data"));)
1096 return;
1097 }
1098
1099 if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
1100 {
1101 limLog(pMac, LOGE, FL("RMC:Ruler_Inform_Cancel lock acquire failed"));
1102 return;
1103 }
1104
1105 /*
1106 * Find the entry for this Group Address.
1107 */
1108 entry = __rmcGroupLookupHashEntry(pMac, pHdr->sa);
1109 if (NULL == entry)
1110 {
1111 PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform_Cancel: No entry"));)
1112 goto done;
1113 }
1114
1115 __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED,
1116 eRMC_RULER_ROLE, pHdr->sa, psessionEntry->selfMacAddr);
1117
1118 /*
1119 * Delete hash entry for this Group address.
1120 */
1121 status = __rmcGroupDeleteHashEntry(pMac, pHdr->sa);
1122 if (eSIR_FAILURE == status)
1123 {
1124 PELOGE(limLog(pMac, LOGE,
1125 FL("RMC: Ruler_Inform_Cancel:hash delete failed"));)
1126 }
1127
1128done:
1129 if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
1130 {
1131 limLog(pMac, LOGE,
1132 FL("RMC: Ruler_Inform_Cancel: lock release failed"));
1133 }
1134 return;
1135}
1136
1137void
1138limProcessRMCMessages(tpAniSirGlobal pMac, eRmcMessageType msgType,
1139 tANI_U32 *pMsgBuf)
1140{
1141
1142 if (pMsgBuf == NULL)
1143 {
1144 PELOGE(limLog(pMac, LOGE, FL("RMC: Buffer is Pointing to NULL"));)
1145 return;
1146 }
1147
1148 limLog(pMac, LOG1, FL("RMC: limProcessRMCMessages: %s"),
1149 __limRulerMessageToString(msgType));
1150
1151 switch (msgType)
1152 {
1153 case eLIM_RMC_ENABLE_REQ:
1154 __limProcessRMCEnableRequest(pMac, pMsgBuf);
1155 break;
1156
1157 case eLIM_RMC_DISABLE_REQ:
1158 __limProcessRMCDisableRequest(pMac, pMsgBuf);
1159 break;
1160
1161 case eLIM_RMC_RULER_SELECT_RESP:
1162 __limProcessRMCRulerSelectResponse(pMac, pMsgBuf);
1163 break;
1164
1165 case eLIM_RMC_RULER_PICK_NEW:
1166 __limProcessRMCRulerPickNew(pMac, pMsgBuf);
1167 break;
1168
1169 case eLIM_RMC_OTA_RULER_INFORM_SELECTED:
1170 __limProcessRMCRulerInformSelected(pMac, pMsgBuf);
1171 break;
1172
1173 case eLIM_RMC_BECOME_RULER_RESP:
1174 __limProcessRMCBecomeRulerResp(pMac, pMsgBuf);
1175 break;
1176
1177 case eLIM_RMC_OTA_RULER_INFORM_CANCELLED:
1178 __limProcessRMCRulerInformCancelled(pMac, pMsgBuf);
1179 break;
1180
1181
1182 default:
1183 break;
1184 } // switch (msgType)
1185 return;
1186} /*** end limProcessRMCMessages() ***/
1187
1188void
1189limRmcInit(tpAniSirGlobal pMac)
1190{
1191 tANI_U32 cfgValue;
1192
1193 if (wlan_cfgGetInt(pMac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
1194 &cfgValue) != eSIR_SUCCESS)
1195 {
1196 /**
1197 * Could not get Action Period Frequency value
1198 * from CFG. Log error.
1199 */
1200 limLog(pMac, LOGP, FL("could not retrieve ActionPeriodFrequency"));
1201 }
1202
1203 cfgValue = SYS_MS_TO_TICKS(cfgValue);
1204
1205 vos_mem_zero(&pMac->rmcContext, sizeof(pMac->rmcContext));
1206
1207 if (!VOS_IS_STATUS_SUCCESS(vos_lock_init(&pMac->rmcContext.lkRmcLock)))
1208 {
1209 PELOGE(limLog(pMac, LOGE, FL("RMC lock init failed!"));)
1210 }
1211
1212 if (tx_timer_create(&pMac->rmcContext.gRmcRulerSelectTimer,
1213 "RMC RSP TIMEOUT",
1214 __rmcRulerSelectTimerHandler,
1215 0 /* param */,
1216 cfgValue, 0,
1217 TX_NO_ACTIVATE) != TX_SUCCESS)
1218 {
1219 limLog(pMac, LOGE, FL("could not create RMC response timer"));
1220 }
1221
1222 pMac->rmcContext.rmcTimerValInTicks = cfgValue;
1223}
1224
1225void
1226limRmcCleanup(tpAniSirGlobal pMac)
1227{
1228 limRmcIbssDelete(pMac);
1229
1230 if (!VOS_IS_STATUS_SUCCESS(vos_lock_destroy(&pMac->rmcContext.lkRmcLock)))
1231 {
1232 PELOGE(limLog(pMac, LOGE, FL("RMC lock destroy failed!"));)
1233 }
1234
1235 tx_timer_delete(&pMac->rmcContext.gRmcRulerSelectTimer);
1236}
1237
1238void
1239limRmcTransmitterDelete(tpAniSirGlobal pMac, tSirMacAddr transmitter)
1240{
1241 if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
1242 {
1243 limLog(pMac, LOGE,
1244 FL("RMC: limRMCTransmitterDelete lock acquire failed"));
1245 return;
1246 }
1247
1248 __rmcGroupDeleteHashEntry(pMac, transmitter);
1249
1250 if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
1251 {
1252 limLog(pMac, LOGE,
1253 FL("RMC: limRMCTransmitterDelete lock release failed"));
1254 }
1255
1256 limLog(pMac, LOG1, FL("RMC: limRmcTransmitterDelete complete"));
1257}
1258
1259void
1260limRmcIbssDelete(tpAniSirGlobal pMac)
1261{
1262 tpPESession psessionEntry;
1263 tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 };
1264
1265 /*
1266 * This API relies on a single active IBSS session.
1267 */
1268 psessionEntry = limIsIBSSSessionActive(pMac);
1269 if (NULL == psessionEntry)
1270 {
1271 PELOGE(limLog(pMac, LOGE, FL("RMC: limRmcIbssDelete:No active IBSS"));)
1272 return;
1273 }
1274
1275 if (VOS_FALSE == vos_mem_compare(&zeroMacAddr,
1276 &pMac->rmcContext.ruler, sizeof(tSirMacAddr)))
1277 {
1278 __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED,
1279 eRMC_TRANSMITTER_ROLE, psessionEntry->selfMacAddr,
1280 pMac->rmcContext.ruler);
1281 }
1282
1283 if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
1284 {
1285 limLog(pMac, LOGE,
1286 FL("RMC: limRmcIbssDelete lock acquire failed"));
1287 return;
1288 }
1289
1290 /* Cancel pending timer */
1291 tx_timer_deactivate(&pMac->rmcContext.gRmcRulerSelectTimer);
1292
1293 /* Delete all entries from Ruler database. */
1294 __rmcGroupDeleteAllEntries(pMac);
1295
1296 if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
1297 {
1298 limLog(pMac, LOGE,
1299 FL("RMC: limRmcIbssDelete lock release failed"));
1300 }
1301
1302 limLog(pMac, LOG1, FL("RMC: limRmcIbssDelete complete"));
1303}
1304
1305void
1306limRmcDumpStatus(tpAniSirGlobal pMac)
1307{
1308 tLimRmcGroupContext *entry;
1309 int index, count;
1310
1311 if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock)))
1312 {
1313 limLog(pMac, LOGE,
1314 FL("RMC: limRmcDumpStatus lock acquire failed"));
1315 return;
1316 }
1317
1318
1319 limLog(pMac, LOGE, FL(" ----- RMC Transmitter Information ----- \n"));
1320 limLog(pMac, LOGE,
1321 FL(" Ruler Address | RMC State \n"));
1322
1323 if (pMac->rmcContext.state != eRMC_RULER_NOT_SELECTED)
1324 {
1325 limLog(pMac,LOGE, FL( MAC_ADDRESS_STR " | %s\n"),
1326 MAC_ADDR_ARRAY(pMac->rmcContext.ruler),
1327 __limMcastTxStateToString(pMac->rmcContext.state));
1328 }
1329
1330 limLog( pMac,LOGE, FL(" ----- RMC Ruler Information ----- \n"));
1331 limLog( pMac,LOGE, FL(" Transmitter Address\n"));
1332
1333 count = 0;
1334 for (index = 0; index < RMC_MCAST_GROUPS_HASH_SIZE; index++)
1335 {
1336 entry = pMac->rmcContext.rmcGroupRxHashTable[index];
1337
1338 while (entry)
1339 {
1340 count++;
1341 limLog( pMac,LOGE, FL("%d. " MAC_ADDRESS_STR " \n"),
1342 count, MAC_ADDR_ARRAY(entry->transmitter));
1343 entry = entry->next;
1344 }
1345 }
1346
1347 if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock)))
1348 {
1349 limLog(pMac, LOGE,
1350 FL("RMC: limRmcDumpStatus lock release failed"));
1351 }
1352
1353 return;
1354
1355}
1356
1357VOS_STATUS
1358limRmcTriggerRulerSelection(tpAniSirGlobal pMac, tSirMacAddr macAddr)
1359{
1360 if ((TRUE == pMac->rmcContext.rmcEnabled) &&
1361 (eRMC_RULER_NOT_SELECTED == pMac->rmcContext.state))
1362 {
1363 limLog(pMac, LOG1,
1364 FL("Ruler selection trigerred in FW"));
1365
1366 __limPostMsgRulerReq(pMac, eRMC_SUGGEST_RULER_CMD, macAddr);
1367
1368 pMac->rmcContext.state = eRMC_RULER_ENABLE_REQUESTED;
1369
1370 return VOS_STATUS_SUCCESS;
1371 }
1372 else
1373 {
1374 limLog(pMac, LOG1,
1375 FL("Could not trigger ruler selection: RMC state %d rmcEnabled %d"),
1376 pMac->rmcContext.state, pMac->rmcContext.rmcEnabled);
1377
1378 return VOS_STATUS_E_FAILURE;
1379 }
1380}
1381
1382#endif /* WLAN_FEATURE_RMC */