blob: a8573431e2e70350a8ddfd5f5bee088666072db3 [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 *
24 * Airgo Networks, Inc proprietary. All rights reserved.
25 * This file contains the source code for CFG API functions.
26 *
27 * Author: Kevin Nguyen
28 * Date: 04/09/02
29 * History:-
30 * 04/09/02 Created.
31 * --------------------------------------------------------------------
32 */
33
34#include "palTypes.h"
35#include "cfgPriv.h"
36#include "cfgDebug.h"
37#include "wlan_qct_wda.h"
38
39//---------------------------------------------------------------------
40// Static Variables
41//----------------------------------------------------------------------
42static tCfgCtl __gCfgEntry[CFG_PARAM_MAX_NUM] ;
43static tANI_U32 __gCfgIBufMin[CFG_STA_IBUF_MAX_SIZE] ;
44static tANI_U32 __gCfgIBufMax[CFG_STA_IBUF_MAX_SIZE] ;
45static tANI_U32 __gCfgIBuf[CFG_STA_IBUF_MAX_SIZE] ;
46static tANI_U8 __gCfgSBuf[CFG_STA_SBUF_MAX_SIZE] ;
47static tANI_U8 __gSBuffer[CFG_MAX_STR_LEN] ;
48static tANI_U32 __gParamList[WNI_CFG_MAX_PARAM_NUM +
49 WNI_CFG_GET_PER_STA_STAT_RSP_NUM];
50
51static void Notify(tpAniSirGlobal, tANI_U16, tANI_U32);
52
53
54// ---------------------------------------------------------------------
55tANI_U32 cfgNeedRestart(tpAniSirGlobal pMac, tANI_U16 cfgId)
56{
57 return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RESTART) ;
58}
59
60// ---------------------------------------------------------------------
61tANI_U32 cfgNeedReload(tpAniSirGlobal pMac, tANI_U16 cfgId)
62{
63 return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RELOAD) ;
64}
65
66// ---------------------------------------------------------------------
67/**
68 * wlan_cfgInit()
69 *
70 * FUNCTION:
71 * CFG initialization function.
72 *
73 * LOGIC:
74 * Please see Configuration & Statistic Collection Micro-Architecture
75 * specification for the pseudocode.
76 *
77 * ASSUMPTIONS:
78 * None.
79 *
80 * NOTE:
81 * This function must be called during system initialization.
82 *
83 * @param None
84 * @return None.
85 */
86
87void
88wlan_cfgInit(tpAniSirGlobal pMac)
89{
90 // Set status to not-ready
91 pMac->cfg.gCfgStatus = CFG_INCOMPLETE;
92
93 // Send CFG_DNLD_REQ to host
94 PELOGW(cfgLog(pMac, LOGW, FL("Sending CFG_DNLD_REQ\n"));)
95 cfgSendHostMsg(pMac, WNI_CFG_DNLD_REQ, WNI_CFG_DNLD_REQ_LEN,
96 WNI_CFG_DNLD_REQ_NUM, 0, 0, 0);
97
98} /*** end wlan_cfgInit() ***/
99
100
101//---------------------------------------------------------------------
102#if (WNI_POLARIS_FW_PRODUCT != AP)
103tSirRetStatus cfgInit(tpAniSirGlobal pMac)
104{
105 pMac->cfg.gCfgIBufMin = __gCfgIBufMin;
106 pMac->cfg.gCfgIBufMax = __gCfgIBufMax;
107 pMac->cfg.gCfgIBuf = __gCfgIBuf;
108 pMac->cfg.gCfgSBuf = __gCfgSBuf;
109 pMac->cfg.gSBuffer = __gSBuffer;
110 pMac->cfg.gCfgEntry = __gCfgEntry;
111 pMac->cfg.gParamList = __gParamList;
112
113 return (eSIR_SUCCESS);
114}
115
116//----------------------------------------------------------------------
117void cfgDeInit(tpAniSirGlobal pMac)
118{
119 pMac->cfg.gCfgIBufMin = NULL;
120 pMac->cfg.gCfgIBufMax = NULL;
121 pMac->cfg.gCfgIBuf = NULL;
122 pMac->cfg.gCfgSBuf = NULL;
123 pMac->cfg.gSBuffer = NULL;
124 pMac->cfg.gCfgEntry = NULL;
125 pMac->cfg.gParamList = NULL;
126}
127#endif
128
129// ---------------------------------------------------------------------
130/**
131 * cfgSetInt()
132 *
133 * FUNCTION:
134 * This function is called to update an integer parameter.
135 *
136 * LOGIC:
137 *
138 * ASSUMPTIONS:
139 * - Range checking is performed by the calling function. In case this
140 * function call is being triggered by a request from host, then host
141 * is responsible for performing range checking before sending the
142 * request.
143 *
144 * - Host RW permission checking should already be done prior to calling
145 * this function by the message processing function.
146 *
147 * NOTE:
148 *
149 * @param cfgId: 16-bit CFG parameter ID
150 * @param value: 32-bit unsigned value
151 *
152 * @return eSIR_SUCCESS : request completed successfully \n
153 * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID \n
154 */
155
156tSirRetStatus
157cfgSetInt(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 value)
158{
159 tANI_U32 index;
160 tANI_U32 control, mask;
161 tSirRetStatus retVal;
162
163 if (cfgId >= CFG_PARAM_MAX_NUM)
164 {
165 PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d\n"), cfgId);)
166 return eSIR_CFG_INVALID_ID;
167 }
168
169 control = pMac->cfg.gCfgEntry[cfgId].control;
170 index = control & CFG_BUF_INDX_MASK;
171 retVal = eSIR_SUCCESS;
172
173#if (WNI_POLARIS_FW_PRODUCT == AP)
174 if (index >= CFG_AP_IBUF_MAX_SIZE)
175#else
176 if (index >= CFG_STA_IBUF_MAX_SIZE)
177#endif
178 {
179 PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d\n"), index);)
180 retVal = eSIR_CFG_INVALID_ID;
181 return retVal;
182 }
183
184 // Check if parameter is valid
185 if ((control & CFG_CTL_VALID) == 0)
186 {
187 PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d\n"), cfgId);)
188 retVal = eSIR_CFG_INVALID_ID;
189 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700190 else if ((pMac->cfg.gCfgIBufMin[index] > value) ||
191 (pMac->cfg.gCfgIBufMax[index] < value))
192 {
193 PELOGE(cfgLog(pMac, LOGE, FL("Value %d out of range [%d,%d] cfg id %d\n"),
194 value, pMac->cfg.gCfgIBufMin[index],
195 pMac->cfg.gCfgIBufMax[index], cfgId);)
196 retVal = eSIR_CFG_INVALID_ID;
197 }
198 else
199 {
200 // Write integer value
201 pMac->cfg.gCfgIBuf[index] = value;
202
203 // Update hardware if necessary
204 mask = control & CFG_CTL_NTF_MASK;
205 if ((mask & CFG_CTL_NTF_HW) != 0)
206 PELOGE(cfgLog(pMac, LOGE, FL("CFG Notify HW not supported!!!\n"));)
207
208 // Notify other modules if necessary
209 if ((mask & CFG_CTL_NTF_MASK) != 0)
210 Notify(pMac, cfgId, mask);
211
212 }
213
214 return (retVal);
215
216} /*** end cfgSetInt ***/
217
218// ---------------------------------------------------------------------
219/**
220 * cfgCheckValid()
221 *
222 * FUNCTION:
223 * This function is called to check if a parameter is valid
224 *
225 * LOGIC:
226 *
227 * ASSUMPTIONS:
228 *
229 * NOTE:
230 *
231 * @param cfgId: 16-bit CFG parameter ID
232 *
233 * @return eSIR_SUCCESS: request completed successfully
234 * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
235 */
236
237tSirRetStatus
238cfgCheckValid(tpAniSirGlobal pMac, tANI_U16 cfgId)
239{
240 tANI_U32 control;
241
242 if (cfgId >= CFG_PARAM_MAX_NUM)
243 {
244 PELOG3(cfgLog(pMac, LOG3, FL("Invalid cfg id %d\n"), cfgId);)
245 return(eSIR_CFG_INVALID_ID);
246 }
247
248 control = pMac->cfg.gCfgEntry[cfgId].control;
249
250 // Check if parameter is valid
251 if ((control & CFG_CTL_VALID) == 0)
252 {
253 PELOG3(cfgLog(pMac, LOG3, FL("Not valid cfg id %d\n"), cfgId);)
254 return(eSIR_CFG_INVALID_ID);
255 }
256 else
257 return(eSIR_SUCCESS);
258
259} /*** end cfgCheckValid() ***/
260
261// ---------------------------------------------------------------------
262/**
263 * wlan_cfgGetInt()
264 *
265 * FUNCTION:
266 * This function is called to read an integer parameter.
267 *
268 * LOGIC:
269 *
270 * ASSUMPTIONS:
271 *
272 * NOTE:
273 *
274 * @param cfgId: 16-bit CFG parameter ID
275 * @param pVal: address where parameter value will be written
276 *
277 * @return eSIR_SUCCESS: request completed successfully
278 * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
279 */
280
281tSirRetStatus
282wlan_cfgGetInt(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 *pValue)
283{
284 tANI_U32 index;
285 tANI_U32 control;
286 tSirRetStatus retVal;
287
288 if (cfgId >= CFG_PARAM_MAX_NUM)
289 {
290 PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d\n"), cfgId);)
291 retVal = eSIR_CFG_INVALID_ID;
292 return retVal;
293 }
294
295 control = pMac->cfg.gCfgEntry[cfgId].control;
296 index = control & CFG_BUF_INDX_MASK;
297 retVal = eSIR_SUCCESS;
298
299#if (WNI_POLARIS_FW_PRODUCT == AP)
300 if (index >= CFG_AP_IBUF_MAX_SIZE)
301#else
302 if (index >= CFG_STA_IBUF_MAX_SIZE)
303#endif
304 {
305 PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d\n"), index);)
306 retVal = eSIR_CFG_INVALID_ID;
307 return retVal;
308 }
309
310 // Check if parameter is valid
311 if ((control & CFG_CTL_VALID) == 0)
312 {
313 PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d\n"), cfgId);)
314 retVal = eSIR_CFG_INVALID_ID;
315 }
316 else {
317 // Get integer value
318 if(index < CFG_AP_IBUF_MAX_SIZE)
319 *pValue = pMac->cfg.gCfgIBuf[index];
320 }
321
322 return (retVal);
323
324} /*** end wlan_cfgGetInt() ***/
325
326#ifdef NOT_CURRENTLY_USED
327// ---------------------------------------------------------------------
328/**
329 * cfgIncrementInt()
330 *
331 * FUNCTION:
332 * This function is called to increment an integer parameter by n.
333 *
334 * LOGIC:
335 *
336 * ASSUMPTIONS:
337 * - No range checking will be performed.
338 * - Host RW permission should be checked prior to calling this
339 * function.
340 *
341 * NOTE:
342 *
343 * @param cfgId: 16-bit CFG parameter ID
344 * @param value: increment value
345 *
346 * @return eSIR_SUCCESS: request completed successfully
347 * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
348 */
349
350tSirRetStatus
351cfgIncrementInt(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 value)
352{
353 tANI_U32 index;
354 tANI_U32 control;
355 tSirRetStatus retVal;
356
357 if (cfgId >= CFG_PARAM_MAX_NUM)
358 {
359 PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d\n"), cfgId);)
360 retVal = eSIR_CFG_INVALID_ID;
361 }
362
363 control = pMac->cfg.gCfgEntry[cfgId].control;
364 index = control & CFG_BUF_INDX_MASK;
365 retVal = eSIR_SUCCESS;
366
367 // Check if parameter is valid
368 if ((control & CFG_CTL_VALID) == 0)
369 {
370 PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d\n"), cfgId);)
371 retVal = eSIR_CFG_INVALID_ID;
372 }
373 else
374 {
375 // Increment integer value
376 pMac->cfg.gCfgIBuf[index] += value;
377
378 }
379
380 return (retVal);
381}
382#endif // NOT_CURRENTLY_USED
383
384// ---------------------------------------------------------------------
385/**
386 * cfgSetStr()
387 *
388 * FUNCTION:
389 * This function is called to set a string parameter.
390 *
391 * LOGIC:
392 * This function invokes the cfgSetStrNotify function passing the notify
393 * boolean value set to TRUE. This basically means that HAL needs to be
394 * notified. This is true in the case of non-integrated SOC's or Libra/Volans.
395 * In the case of Prima the cfgSetStrNotify is invoked with the boolean value
396 * set to FALSE.
397 *
398 * ASSUMPTIONS:
399 * - always Notify has to be called
400 *
401 * NOTE:
402 *
403 * @param cfgId: 16-bit CFG parameter ID
404 * @param pStr: address of string data
405 * @param len: string length
406 *
407 * @return eSIR_SUCCESS: request completed successfully
408 * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
409 * @return eSIR_CFG_INVALID_LEN: invalid parameter length
410 *
411 */
412
413tSirRetStatus cfgSetStr(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U8 *pStr,
414 tANI_U32 length)
415{
416 return cfgSetStrNotify( pMac, cfgId, pStr, length, TRUE );
417}
418
419// ---------------------------------------------------------------------
420/**
421 * cfgSetStrNotify()
422 *
423 * FUNCTION:
424 * This function is called to set a string parameter.
425 *
426 * LOGIC:
427 *
428 * ASSUMPTIONS:
429 * - No length checking will be performed. Should be done by calling
430 * module.
431 * - Host RW permission should be checked prior to calling this
432 * function.
433 *
434 * NOTE:
435 *
436 * @param cfgId: 16-bit CFG parameter ID
437 * @param pStr: address of string data
438 * @param len: string length
439 * @param notifyMod. Notify respective Module
440 *
441 * @return eSIR_SUCCESS: request completed successfully
442 * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
443 * @return eSIR_CFG_INVALID_LEN: invalid parameter length
444 *
445 */
446
447tSirRetStatus
448cfgSetStrNotify(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U8 *pStr,
449 tANI_U32 length, int notifyMod)
450{
451 tANI_U8 *pDst, *pDstEnd;
452 tANI_U32 index, paramLen, control, mask;
453 tSirRetStatus retVal;
454
455 if (cfgId >= CFG_PARAM_MAX_NUM)
456 {
457 PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d\n"), cfgId);)
458 return eSIR_CFG_INVALID_ID;
459 }
460
461 control = pMac->cfg.gCfgEntry[cfgId].control;
462 index = control & CFG_BUF_INDX_MASK;
463 retVal = eSIR_SUCCESS;
464
465 // Check if parameter is valid
466 if ((control & CFG_CTL_VALID) == 0)
467 {
468 PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d\n"), cfgId);)
469 retVal = eSIR_CFG_INVALID_ID;
470 }
471 else if (index >= CFG_STA_SBUF_MAX_SIZE)
472 {
473 PELOGE(cfgLog(pMac, LOGE, FL("Invalid Sbuf index %d (max size %d)\n"),
474 index, CFG_STA_SBUF_MAX_SIZE);)
475 retVal = eSIR_CFG_INVALID_ID;
476 }
477 else
478 {
479 pDst = &pMac->cfg.gCfgSBuf[index];
480 paramLen = *pDst++;
481 if (length > paramLen)
482 {
483 PELOGE(cfgLog(pMac, LOGE, FL("Invalid length %d (>%d) cfg id %d\n"),
484 length, paramLen, cfgId);)
485 retVal = eSIR_CFG_INVALID_LEN;
486 }
487 else
488 {
489 *pDst++ = (tANI_U8)length;
490 pDstEnd = pDst + length;
491 while (pDst < pDstEnd)
492 {
493 *pDst++ = *pStr++;
494 }
495
496 if(notifyMod)
497 {
498 // Update hardware if necessary
499 mask = control & CFG_CTL_NTF_MASK;
500 if ((mask & CFG_CTL_NTF_HW) != 0)
501 {
502 PELOGE(cfgLog(pMac, LOGE, FL("CFG Notify HW not supported!!!\n"));)
503 }
504
505 // Notify other modules if necessary
506 if ( (mask & CFG_CTL_NTF_MASK) != 0)
507 {
508 Notify(pMac, cfgId, mask);
509 }
510 }
511 }
512
513 }
514
515 return (retVal);
516
517} /*** end cfgSetStrNotify() ***/
518
519// ---------------------------------------------------------------------
520/**
521 * wlan_cfgGetStr()
522 *
523 * FUNCTION:
524 * This function is called to get a string parameter.
525 *
526 * LOGIC:
527 *
528 * ASSUMPTIONS:
529 * - Host RW permission should be checked prior to calling this
530 * function.
531 *
532 * NOTE:
533 *
534 * @param cfgId: 16-bit CFG parameter ID
535 * @param pBuf: address of string buffer
536 * @param pLen: address of max buffer length
537 * actual length will be returned at this address
538 *
539 * @return eSIR_SUCCESS: request completed successfully
540 * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
541 * @return eSIR_CFG_INVALID_LEN: invalid parameter length
542 *
543 */
544
545tSirRetStatus
546wlan_cfgGetStr(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U8 *pBuf, tANI_U32 *pLength)
547{
548 tANI_U8 *pSrc, *pSrcEnd;
549 tANI_U32 index, control;
550 tSirRetStatus retVal;
551
552 if (cfgId >= CFG_PARAM_MAX_NUM)
553 {
554 PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d\n"), cfgId);)
555 retVal = eSIR_CFG_INVALID_ID;
556 return retVal;
557 }
558
559 control = pMac->cfg.gCfgEntry[cfgId].control;
560 index = control & CFG_BUF_INDX_MASK;
561 retVal = eSIR_SUCCESS;
562
563#if (WNI_POLARIS_FW_PRODUCT == AP)
564 if (index >= CFG_AP_SBUF_MAX_SIZE)
565#else
566 if (index >= CFG_STA_SBUF_MAX_SIZE)
567#endif
568 {
569 PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d\n"), index);)
570 retVal = eSIR_CFG_INVALID_ID;
571 return retVal;
572 }
573
574 // Check if parameter is valid
575 if ((control & CFG_CTL_VALID) == 0)
576 {
577 PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d\n"), cfgId);)
578 retVal = eSIR_CFG_INVALID_ID;
579 }
580 else
581 {
582 // Get string
583 pSrc = &pMac->cfg.gCfgSBuf[index];
584 pSrc++; // skip over max length
585 if (*pLength < *pSrc)
586 {
587 PELOGE(cfgLog(pMac, LOGE, FL("Invalid length %d (<%d) cfg id %d\n"),
588 *pLength, *pSrc, cfgId);)
589 retVal = eSIR_CFG_INVALID_LEN;
590 }
591 else
592 {
593 *pLength = *pSrc++; // save parameter length
594 pSrcEnd = pSrc + *pLength;
595 while (pSrc < pSrcEnd)
596 *pBuf++ = *pSrc++;
597 }
598 }
599
600 return (retVal);
601
602} /*** end wlan_cfgGetStr() ***/
603
604// ---------------------------------------------------------------------
605/**
606 * wlan_cfgGetStrMaxLen()
607 *
608 * FUNCTION:
609 * This function is called to get a string maximum length.
610 *
611 * LOGIC:
612 *
613 * ASSUMPTIONS:
614 * - Host RW permission should be checked prior to calling this
615 * function.
616 *
617 * NOTE:
618 *
619 * @param cfgId: 16-bit CFG parameter ID
620 * @param pLen: maximum length will be returned at this address
621 *
622 * @return eSIR_SUCCESS: request completed successfully
623 * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
624 *
625 */
626
627tSirRetStatus
628wlan_cfgGetStrMaxLen(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 *pLength)
629{
630 tANI_U32 index, control;
631 tSirRetStatus retVal;
632
633 if (cfgId >= CFG_PARAM_MAX_NUM)
634 {
635 PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d\n"), cfgId);)
636 retVal = eSIR_CFG_INVALID_ID;
637 }
638
639 control = pMac->cfg.gCfgEntry[cfgId].control;
640 index = control & CFG_BUF_INDX_MASK;
641 retVal = eSIR_SUCCESS;
642
643#if (WNI_POLARIS_FW_PRODUCT == AP)
644 if (index >= CFG_AP_SBUF_MAX_SIZE)
645#else
646 if (index >= CFG_STA_SBUF_MAX_SIZE)
647#endif
648 {
649 PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d\n"), index);)
650 retVal = eSIR_CFG_INVALID_ID;
651 return retVal;
652 }
653
654 // Check if parameter is valid
655 if ((control & CFG_CTL_VALID) == 0)
656 {
657 PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d\n"), cfgId);)
658 retVal = eSIR_CFG_INVALID_ID;
659 }
660 else
661 {
662 *pLength = pMac->cfg.gCfgSBuf[index];
663 }
664
665 return (retVal);
666
667} /*** end wlan_cfgGetStrMaxLen() ***/
668
669// ---------------------------------------------------------------------
670/**
671 * wlan_cfgGetStrLen()
672 *
673 * FUNCTION:
674 * This function is called to get a string length.
675 *
676 * LOGIC:
677 *
678 * ASSUMPTIONS:
679 * - Host RW permission should be checked prior to calling this
680 * function.
681 *
682 * NOTE:
683 *
684 * @param cfgId: 16-bit CFG parameter ID
685 * @param pLen: current length will be returned at this address
686 *
687 * @return eSIR_SUCCESS: request completed successfully
688 * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
689 *
690 */
691
692tSirRetStatus
693wlan_cfgGetStrLen(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 *pLength)
694{
695 tANI_U32 index, control;
696 tSirRetStatus retVal;
697
698 if (cfgId >= CFG_PARAM_MAX_NUM)
699 {
700 PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d\n"), cfgId);)
701 retVal = eSIR_CFG_INVALID_ID;
702 }
703
704 control = pMac->cfg.gCfgEntry[cfgId].control;
705 index = control & CFG_BUF_INDX_MASK;
706 retVal = eSIR_SUCCESS;
707
708#if (WNI_POLARIS_FW_PRODUCT == AP)
709 if (index >= CFG_AP_SBUF_MAX_SIZE-1)
710#else
711 if (index >= CFG_STA_SBUF_MAX_SIZE-1)
712#endif
713 {
714 PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d\n"), index);)
715 retVal = eSIR_CFG_INVALID_ID;
716 return retVal;
717 }
718
719 // Check if parameter is valid
720 if ((control & CFG_CTL_VALID) == 0)
721 {
722 PELOGE(cfgLog(pMac, LOGE, FL("Not valid cfg id %d\n"), cfgId);)
723 retVal = eSIR_CFG_INVALID_ID;
724 }
725 else
726 {
727 *pLength = pMac->cfg.gCfgSBuf[index+1];
728 }
729
730 return (retVal);
731
732} /*** end wlan_cfgGetStrLen() ***/
733
734
735
736/*-------------------------------------------------------------
737\fn cfgGetDot11dTransmitPower
738\brief This function returns the regulatory max transmit power
739\param pMac
740\return tPowerdBm - Power
741\-------------------------------------------------------------*/
742static tPowerdBm
743cfgGetDot11dTransmitPower(tpAniSirGlobal pMac, tANI_U16 cfgId,
744 tANI_U32 cfgLength, tANI_U8 channel)
745{
746 tANI_U8 *pCountryInfo = NULL;
747 tANI_U8 count = 0;
748 tPowerdBm maxTxPwr = WDA_MAX_TXPOWER_INVALID;
749 eHalStatus status;
750
751 /* At least one element is present */
752 if(cfgLength < sizeof(tSirMacChanInfo))
753 {
754 PELOGE(cfgLog(pMac, LOGE, FL("Invalid CFGLENGTH %d while getting 11d txpower"), cfgLength);)
755 goto error;
756 }
757
758 status = palAllocateMemory(pMac->hHdd, (void **)&pCountryInfo, cfgLength);
759 if (status != eHAL_STATUS_SUCCESS)
760 {
761 cfgLog(pMac, LOGP, FL(" palAllocateMemory() failed, status = %d"), status);
762 goto error;
763 }
764 /* The CSR will always update this CFG. The contents will be from country IE if regulatory domain
765 * is enabled on AP else will contain EEPROM contents
766 */
767 if (wlan_cfgGetStr(pMac, cfgId, pCountryInfo, &cfgLength) != eSIR_SUCCESS)
768 {
769 palFreeMemory(pMac->hHdd, pCountryInfo);
770 pCountryInfo = NULL;
771
772 cfgLog(pMac, LOGP, FL("Failed to retrieve 11d configuration parameters while retrieving 11d tuples"));
773 goto error;
774 }
775 /* Identify the channel and maxtxpower */
776 while(count <= (cfgLength - (sizeof(tSirMacChanInfo))))
777 {
778 tANI_U8 firstChannel, maxChannels;
779
780 firstChannel = pCountryInfo[count++];
781 maxChannels = pCountryInfo[count++];
782 maxTxPwr = pCountryInfo[count++];
783
784 if((channel >= firstChannel) &&
785 (channel < (firstChannel + maxChannels)))
786 {
787 break;
788 }
789 }
790
791error:
792 if(NULL != pCountryInfo)
793 palFreeMemory(pMac->hHdd, pCountryInfo);
794
795 return maxTxPwr;
796}
797
798
799/**----------------------------------------------------------------------
800\fn cfgGetRegulatoryMaxTransmitPower
801
802\brief Gets regulatory tx power on the current channel.
803
804\param pMac
805\param channel
806\param rfBand
807 -----------------------------------------------------------------------*/
808tPowerdBm cfgGetRegulatoryMaxTransmitPower(tpAniSirGlobal pMac, tANI_U8 channel)
809{
810 tANI_U32 cfgLength = 0;
811 tANI_U16 cfgId = 0;
812 tPowerdBm maxTxPwr;
813 eRfBandMode rfBand = eRF_BAND_UNKNOWN;
814
815 if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
816 (channel <= SIR_11A_CHANNEL_END))
817 rfBand = eRF_BAND_5_GHZ;
818 else
819 rfBand = eRF_BAND_2_4_GHZ;
820
821
822 /* Get the max transmit power for current channel for the current regulatory domain */
823 switch (rfBand)
824 {
825 case eRF_BAND_2_4_GHZ:
826 cfgId = WNI_CFG_MAX_TX_POWER_2_4;
827 cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN;
828 PELOG2(cfgLog(pMac, LOG2, FL("HAL: Reading CFG for 2.4 GHz channels to get regulatory max tx power"));)
829 break;
830
831 case eRF_BAND_5_GHZ:
832 cfgId = WNI_CFG_MAX_TX_POWER_5;
833 cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN;
834 PELOG2(cfgLog(pMac, LOG2, FL("HAL: Reading CFG for 5.0 GHz channels to get regulatory max tx power"));)
835 break;
836
837 case eRF_BAND_UNKNOWN:
838 default:
839 PELOG2(cfgLog(pMac, LOG2, FL("HAL: Invalid current working band for the device"));)
840 return WDA_MAX_TXPOWER_INVALID; //Its return, not break.
841 }
842
843 maxTxPwr = cfgGetDot11dTransmitPower(pMac, cfgId, cfgLength, channel);
844
845 return (maxTxPwr);
846}
847
848// ---------------------------------------------------------------------
849/**
850 * cfgGetCapabilityInfo
851 *
852 * FUNCTION:
853 *
854 * LOGIC:
855 *
856 * ASSUMPTIONS:
857 *
858 * NOTE:
859 *
860 * @param None
861 * @return None
862 */
863
864tSirRetStatus
865cfgGetCapabilityInfo(tpAniSirGlobal pMac, tANI_U16 *pCap,tpPESession sessionEntry)
866{
867 tANI_U32 val = 0;
868 tpSirMacCapabilityInfo pCapInfo;
869 tLimSystemRole systemRole = limGetSystemRole(sessionEntry);
870
871 *pCap = 0;
872 pCapInfo = (tpSirMacCapabilityInfo) pCap;
873
874 if (systemRole == eLIM_STA_IN_IBSS_ROLE)
875 pCapInfo->ibss = 1; // IBSS bit
876 else if ( (systemRole == eLIM_AP_ROLE) ||(systemRole == eLIM_BT_AMP_AP_ROLE)||(systemRole == eLIM_BT_AMP_STA_ROLE) ||
877 (systemRole == eLIM_STA_ROLE) )
878 pCapInfo->ess = 1; // ESS bit
879#if defined WLAN_FEATURE_P2P
880 else if (limGetSystemRole(sessionEntry) == eLIM_P2P_DEVICE_ROLE )
881 {
882 pCapInfo->ess = 0;
883 pCapInfo->ibss = 0;
884 }
885#endif
886 else
887 cfgLog(pMac, LOGP, FL("can't get capability, role is UNKNOWN!!\n"));
888
889#if (WNI_POLARIS_FW_PRODUCT == AP)
890 if( (systemRole == eLIM_AP_ROLE) )
891 {
892 // CF-pollable bit
893 if (wlan_cfgGetInt(pMac, WNI_CFG_CF_POLLABLE, &val) != eSIR_SUCCESS)
894 {
895 cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_CF_POLLABLE failed\n"));
896 return eSIR_FAILURE;
897 }
898 if (val)
899 pCapInfo->cfPollable = 1;
900
901 // CF-poll request bit
902 if (wlan_cfgGetInt(pMac, WNI_CFG_CF_POLL_REQUEST, &val) != eSIR_SUCCESS)
903 {
904 cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_CF_POLL_REQUEST failed\n"));
905 return eSIR_FAILURE;
906 }
907 if (val)
908 pCapInfo->cfPollReq = 1;
909 }
910#endif
911
912#ifdef WLAN_SOFTAP_FEATURE
913 if(systemRole == eLIM_AP_ROLE)
914 {
915 val = sessionEntry->privacy;
916 }
917 else
918 {
919#endif
920 // PRIVACY bit
921 if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, &val) != eSIR_SUCCESS)
922 {
923 cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_PRIVACY_ENABLED failed\n"));
924 return eSIR_FAILURE;
925 }
926#ifdef WLAN_SOFTAP_FEATURE
927 }
928#endif
929 if (val)
930 pCapInfo->privacy = 1;
931
932 // Short preamble bit
933 if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS)
934 {
935 cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_SHORT_PREAMBLE failed\n"));
936 return eSIR_FAILURE;
937 }
938 if (val)
939 pCapInfo->shortPreamble = 1;
940
941
942 // PBCC bit
943 pCapInfo->pbcc = 0;
944
945 // Channel agility bit
946 pCapInfo->channelAgility = 0;
947 //If STA/AP operating in 11B mode, don't set rest of the capability info bits.
948 if(sessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11B)
949 return eSIR_SUCCESS;
950
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 // Short slot time bit
952 if (systemRole == eLIM_AP_ROLE)
953 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700954 pCapInfo->shortSlotTime = sessionEntry->shortSlotTimeSupported;
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 }
956 else
957 {
958 if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val)
959 != eSIR_SUCCESS)
960 {
961 cfgLog(pMac, LOGP,
962 FL("cfg get WNI_CFG_11G_SHORT_SLOT_TIME failed\n"));
963 return eSIR_FAILURE;
964 }
965 /* When in STA mode, we need to check if short slot is enabled as well as check if the current operating
966 * mode is short slot time and then decide whether to enable short slot or not. It is safe to check both
967 * cfg values to determine short slot value in this funcn since this funcn is always used after assoc when
968 * these cfg values are already set based on peer's capability. Even in case of IBSS, its value is set to
969 * correct value either in delBSS as part of deleting the previous IBSS or in start BSS as part of coalescing
970 */
971 if (val)
972 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700973 pCapInfo->shortSlotTime = sessionEntry->shortSlotTimeSupported;
974 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700975 }
976
977 // Spectrum Management bit
978 if((eLIM_STA_IN_IBSS_ROLE != systemRole) &&
979 sessionEntry->lim11hEnable )
980 {
981 if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS)
982 {
983 cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_11H_ENABLED failed\n"));
984 return eSIR_FAILURE;
985 }
986 if (val)
987 pCapInfo->spectrumMgt = 1;
988 }
989
990 // QoS bit
991 if (wlan_cfgGetInt(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS)
992 {
993 cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_QOS_ENABLED failed\n"));
994 return eSIR_FAILURE;
995 }
996 if (val)
997 pCapInfo->qos = 1;
998
999 // APSD bit
1000 if (wlan_cfgGetInt(pMac, WNI_CFG_APSD_ENABLED, &val) != eSIR_SUCCESS)
1001 {
1002 cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_APSD_ENABLED failed\n"));
1003 return eSIR_FAILURE;
1004 }
1005 if (val)
1006 pCapInfo->apsd = 1;
1007
1008#if defined WLAN_FEATURE_VOWIFI
1009 if ((limGetSystemRole(sessionEntry) == eLIM_STA_ROLE) )
1010 {
1011 if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS)
1012 {
1013 cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_RRM_ENABLED failed\n"));
1014 return eSIR_FAILURE;
1015 }
1016#if defined WLAN_VOWIFI_DEBUG
1017 PELOGE(cfgLog( pMac, LOGE, "RRM = %d\n",val );)
1018#endif
1019 if (val)
1020 pCapInfo->rrm = 1;
1021 }
1022#endif
1023 //DSSS-OFDM
1024 //FIXME : no config defined yet.
1025
1026 // Block ack bit
1027 if (wlan_cfgGetInt(pMac, WNI_CFG_BLOCK_ACK_ENABLED, &val) != eSIR_SUCCESS)
1028 {
1029 cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_BLOCK_ACK_ENABLED failed\n"));
1030 return eSIR_FAILURE;
1031 }
1032 pCapInfo->delayedBA = (tANI_U16)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
1033 pCapInfo->immediateBA = (tANI_U16)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
1034
1035 return eSIR_SUCCESS;
1036}
1037
1038// --------------------------------------------------------------------
1039/**
1040 * cfgSetCapabilityInfo
1041 *
1042 * FUNCTION:
1043 * This function is called on BP based on the capabilities
1044 * received in SME_JOIN/REASSOC_REQ message.
1045 *
1046 * LOGIC:
1047 *
1048 * ASSUMPTIONS:
1049 *
1050 * NOTE: 1. ESS/IBSS capabilities are based on system role.
1051 * 2. Since PBCC, Channel agility and Extended capabilities
1052 * are not supported, they're not set at CFG
1053 *
1054 * @param pMac Pointer to global MAC structure
1055 * @param caps 16-bit Capability Info field
1056 * @return None
1057 */
1058
1059void
1060cfgSetCapabilityInfo(tpAniSirGlobal pMac, tANI_U16 caps)
1061{
1062#if (defined(ANI_PRODUCT_TYPE_AP))
1063
1064 if (cfgSetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
1065 SIR_MAC_GET_PRIVACY(caps)) != eSIR_SUCCESS)
1066 cfgLog(pMac, LOGP, FL("could not set privacy at CFG\n"));
1067
1068 if (cfgSetInt(pMac, WNI_CFG_SHORT_PREAMBLE,
1069 SIR_MAC_GET_SHORT_PREAMBLE(caps)) != eSIR_SUCCESS)
1070 cfgLog(pMac, LOGP, FL("could not set short preamble at CFG\n"));
1071
1072 if (cfgSetInt(pMac, WNI_CFG_QOS_ENABLED,
1073 SIR_MAC_GET_QOS(caps)) != eSIR_SUCCESS)
1074 cfgLog(pMac, LOGP, FL("could not set qos at CFG\n"));
1075
1076 if (cfgSetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
1077 SIR_MAC_GET_SHORT_SLOT_TIME(caps)) != eSIR_SUCCESS)
1078 cfgLog(pMac, LOGP, FL("could not set short slot time at CFG\n"));
1079
1080 if (cfgSetInt(pMac, WNI_CFG_APSD_ENABLED,
1081 SIR_MAC_GET_APSD(caps)) != eSIR_SUCCESS)
1082 cfgLog(pMac, LOGP, FL("could not set apsd at CFG\n"));
1083
1084 if (cfgSetInt(pMac, WNI_CFG_BLOCK_ACK_ENABLED,
1085 SIR_MAC_GET_BLOCK_ACK(caps)) != eSIR_SUCCESS)
1086 cfgLog(pMac, LOGP, FL("could not set BlockAck at CFG\n"));
1087#endif
1088}
1089
1090
1091// ---------------------------------------------------------------------
1092/**
1093 * cfgCleanup()
1094 *
1095 * FUNCTION:
1096 * CFG cleanup function.
1097 *
1098 * LOGIC:
1099 *
1100 * ASSUMPTIONS:
1101 * None.
1102 *
1103 * NOTE:
1104 * This function must be called during system shutdown.
1105 *
1106 * @param None
1107 *
1108 * @return None.
1109 *
1110 */
1111
1112void
1113cfgCleanup(tpAniSirGlobal pMac)
1114{
1115 // Set status to not-ready
1116 pMac->cfg.gCfgStatus = CFG_INCOMPLETE;
1117
1118} /*** end CfgCleanup() ***/
1119
1120// ---------------------------------------------------------------------
1121/**
1122 * Notify()
1123 *
1124 * FUNCTION:
1125 * This function is called to notify other modules of parameter update.
1126 *
1127 * LOGIC:
1128 *
1129 * ASSUMPTIONS:
1130 *
1131 * NOTE:
1132 *
1133 * @param cfgId: configuration parameter ID
1134 * @param mask: notification mask
1135 *
1136 * @return None.
1137 *
1138 */
1139
1140static void
1141Notify(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 ntfMask)
1142{
1143
1144 tSirMsgQ mmhMsg;
1145
1146 mmhMsg.type = SIR_CFG_PARAM_UPDATE_IND;
1147 mmhMsg.bodyval = (tANI_U32)cfgId;
1148 mmhMsg.bodyptr = NULL;
1149
Jeff Johnsone7245742012-09-05 17:12:55 -07001150 MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type));
Jeff Johnson295189b2012-06-20 16:38:30 -07001151
1152 if ((ntfMask & CFG_CTL_NTF_SCH) != 0)
1153 schPostMessage(pMac, &mmhMsg);
1154
1155 if ((ntfMask & CFG_CTL_NTF_LIM) != 0)
1156 limPostMsgApi(pMac, &mmhMsg);
1157
1158 if ((ntfMask & CFG_CTL_NTF_HAL) != 0)
1159 wdaPostCtrlMsg(pMac, &mmhMsg);
1160
1161 // Notify ARQ
1162
1163} /*** end Notify() ***/
1164
1165// ---------------------------------------------------------------------
1166
1167
1168
1169
1170
1171
1172