support different wifi bt chip auto compatible
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / mt5931_kk / drv_wlan / mgmt / p2p_rlm.c
1 /*
2 ** $Id: @(#) p2p_rlm.c@@
3 */
4
5 /*! \file   "p2p_rlm.c"
6     \brief
7
8 */
9
10 /*******************************************************************************
11 * Copyright (c) 2007 MediaTek Inc.
12 *
13 * All rights reserved. Copying, compilation, modification, distribution
14 * or any other use whatsoever of this material is strictly prohibited
15 * except in accordance with a Software License Agreement with
16 * MediaTek Inc.
17 ********************************************************************************
18 */
19
20 /*******************************************************************************
21 * LEGAL DISCLAIMER
22 *
23 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
24 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
25 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
26 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
27 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
28 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
29 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
30 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
31 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
32 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
33 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
34 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
35 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
36 *
37 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
38 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
39 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
40 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
41 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
42 *
43 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
44 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
45 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
46 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
47 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
48 * (ICC).
49 ********************************************************************************
50 */
51
52
53 /*******************************************************************************
54 *                         C O M P I L E R   F L A G S
55 ********************************************************************************
56 */
57
58 /*******************************************************************************
59 *                    E X T E R N A L   R E F E R E N C E S
60 ********************************************************************************
61 */
62
63 #include "precomp.h"
64
65 extern VOID
66 rlmSyncOperationParams (
67     P_ADAPTER_T         prAdapter,
68     P_BSS_INFO_T        prBssInfo
69     );
70
71 /*******************************************************************************
72 *                              C O N S T A N T S
73 ********************************************************************************
74 */
75
76 /*******************************************************************************
77 *                             D A T A   T Y P E S
78 ********************************************************************************
79 */
80
81 /*******************************************************************************
82 *                            P U B L I C   D A T A
83 ********************************************************************************
84 */
85
86 /*******************************************************************************
87 *                           P R I V A T E   D A T A
88 ********************************************************************************
89 */
90
91 /*******************************************************************************
92 *                                 M A C R O S
93 ********************************************************************************
94 */
95
96 /*******************************************************************************
97 *                   F U N C T I O N   D E C L A R A T I O N S
98 ********************************************************************************
99 */
100
101 /*******************************************************************************
102 *                              F U N C T I O N S
103 ********************************************************************************
104 */
105
106 /*----------------------------------------------------------------------------*/
107 /*!
108 * \brief  Init AP Bss
109 *
110 * \param[in]
111 *
112 * \return none
113 */
114 /*----------------------------------------------------------------------------*/
115 VOID
116 rlmBssInitForAP(
117     P_ADAPTER_T  prAdapter,
118     P_BSS_INFO_T prBssInfo
119     )
120 {
121     ENUM_BAND_T         eBand;
122     UINT_8              ucChannel;
123     ENUM_CHNL_EXT_T     eSCO;
124
125     ASSERT(prAdapter);
126     ASSERT(prBssInfo);
127
128     if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) {
129         return;
130     }
131
132     /* Operation band, channel shall be ready before invoking this function.
133      * Bandwidth may be ready if other network is connected
134      */
135     prBssInfo->fg40mBwAllowed = FALSE;
136     prBssInfo->fgAssoc40mBwAllowed = FALSE;
137     prBssInfo->eBssSCO = CHNL_EXT_SCN;
138
139     if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) {
140         /* In this case, the first BSS's SCO is 40MHz and known, so AP can
141          * apply 40MHz bandwidth, but the first BSS's SCO may be changed
142          * later if its Beacon lost timeout occurs
143          */
144         if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) &&
145             eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel &&
146             eBand == prBssInfo->eBand) {
147             prBssInfo->eBssSCO = eSCO;
148         }
149         else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) {
150             prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo);
151         }
152
153         if (prBssInfo->eBssSCO != CHNL_EXT_SCN) {
154             prBssInfo->fg40mBwAllowed = TRUE;
155             prBssInfo->fgAssoc40mBwAllowed = TRUE;
156
157             prBssInfo->ucHtOpInfo1 = (UINT_8)
158                 (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH);
159
160             rlmUpdateBwByChListForAP(prAdapter, prBssInfo);
161         }
162     }
163
164     DBGLOG(RLM, INFO, ("WLAN AP SCO=%d\n", prBssInfo->eBssSCO));
165 }
166
167 /*----------------------------------------------------------------------------*/
168 /*!
169 * \brief For probe response (GO, IBSS) and association response
170 *
171 * \param[in]
172 *
173 * \return none
174 */
175 /*----------------------------------------------------------------------------*/
176 VOID
177 rlmRspGenerateObssScanIE (
178     P_ADAPTER_T     prAdapter,
179     P_MSDU_INFO_T   prMsduInfo
180     )
181 {
182     P_BSS_INFO_T            prBssInfo;
183     P_IE_OBSS_SCAN_PARAM_T  prObssScanIe;
184     P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
185
186     ASSERT(prAdapter);
187     ASSERT(prMsduInfo);
188     ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
189
190     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
191
192     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
193     ASSERT(prBssInfo);
194
195     if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) &&
196         prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT &&
197         (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) &&
198         prBssInfo->eBand == BAND_2G4 &&
199         prBssInfo->eBssSCO != CHNL_EXT_SCN) {
200
201         prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T)
202                 (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
203
204         /* Add 20/40 BSS coexistence IE */
205         prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS;
206         prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN;
207
208         prObssScanIe->u2ScanPassiveDwell =
209                         dot11OBSSScanPassiveDwell;
210         prObssScanIe->u2ScanActiveDwell =
211                         dot11OBSSScanActiveDwell;
212         prObssScanIe->u2TriggerScanInterval =
213                         dot11BSSWidthTriggerScanInterval;
214         prObssScanIe->u2ScanPassiveTotalPerChnl =
215                         dot11OBSSScanPassiveTotalPerChannel;
216         prObssScanIe->u2ScanActiveTotalPerChnl =
217                         dot11OBSSScanActiveTotalPerChannel;
218         prObssScanIe->u2WidthTransDelayFactor =
219                         dot11BSSWidthChannelTransitionDelayFactor;
220         prObssScanIe->u2ScanActivityThres =
221                         dot11OBSSScanActivityThreshold;
222
223         ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN+ ELEM_MAX_LEN_OBSS_SCAN));
224
225         prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe);
226     }
227 }
228
229 /*----------------------------------------------------------------------------*/
230 /*!
231 * \brief P2P GO.
232 *
233 * \param[in]
234 *
235 * \return none
236 */
237 /*----------------------------------------------------------------------------*/
238 BOOLEAN
239 rlmUpdateBwByChListForAP (
240     P_ADAPTER_T         prAdapter,
241     P_BSS_INFO_T        prBssInfo
242     )
243 {
244     UINT_8              ucLevel;
245     BOOLEAN             fgBwChange;
246
247     ASSERT(prAdapter);
248     ASSERT(prBssInfo);
249
250     fgBwChange = FALSE;
251
252     if (prBssInfo->eBssSCO == CHNL_EXT_SCN) {
253         return fgBwChange;
254     }
255
256     ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand,
257                     prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO);
258
259     if (ucLevel == CHNL_LEVEL0) {
260         /* Forced to 20MHz, so extended channel is SCN and STA width is zero */
261         prBssInfo->fgObssActionForcedTo20M = TRUE;
262
263         if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) {
264             prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN;
265             fgBwChange = TRUE;
266         }
267
268         cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer,
269                 OBSS_20_40M_TIMEOUT * MSEC_PER_SEC);
270     }
271
272     /* Clear up all channel lists */
273     prBssInfo->auc2G_20mReqChnlList[0] = 0;
274     prBssInfo->auc2G_NonHtChnlList[0] = 0;
275     prBssInfo->auc2G_PriChnlList[0] = 0;
276     prBssInfo->auc2G_SecChnlList[0] = 0;
277     prBssInfo->auc5G_20mReqChnlList[0] = 0;
278     prBssInfo->auc5G_NonHtChnlList[0] = 0;
279     prBssInfo->auc5G_PriChnlList[0] = 0;
280     prBssInfo->auc5G_SecChnlList[0] = 0;
281
282     return fgBwChange;
283 }
284
285 /*----------------------------------------------------------------------------*/
286 /*!
287 * \brief
288 *
289 * \param[in]
290 *
291 * \return none
292 */
293 /*----------------------------------------------------------------------------*/
294 VOID
295 rlmProcessPublicAction (
296     P_ADAPTER_T     prAdapter,
297     P_SW_RFB_T      prSwRfb
298     )
299 {
300     P_ACTION_20_40_COEXIST_FRAME    prRxFrame;
301     P_IE_20_40_COEXIST_T            prCoexist;
302     P_IE_INTOLERANT_CHNL_REPORT_T   prChnlReport;
303     P_BSS_INFO_T                    prBssInfo;
304     P_STA_RECORD_T                  prStaRec;
305     PUINT_8                         pucIE;
306     UINT_16                         u2IELength, u2Offset;
307     UINT_8                          i, j;
308
309     ASSERT(prAdapter);
310     ASSERT(prSwRfb);
311
312     prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader;
313     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
314
315     if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST ||
316         !prStaRec || prStaRec->ucStaState != STA_STATE_3 ||
317         prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) ||
318         HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) !=
319         NETWORK_TYPE_P2P_INDEX) {
320         return;
321     }
322
323     prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
324     ASSERT(prBssInfo);
325
326     if (!IS_BSS_ACTIVE(prBssInfo) ||
327         prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT ||
328         prBssInfo->eBssSCO == CHNL_EXT_SCN) {
329         return;
330     }
331
332     prCoexist = &prRxFrame->rBssCoexist;
333     if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT|BSS_COEXIST_20M_REQ)) {
334         ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
335         for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] &&
336              i <= CHNL_LIST_SZ_2G; i++) {
337             if (prBssInfo->auc2G_20mReqChnlList[i] ==
338                 prBssInfo->ucPrimaryChannel) {
339                 break;
340             }
341         }
342         if ((i > prBssInfo->auc2G_20mReqChnlList[0]) &&
343             (i <= CHNL_LIST_SZ_2G)){
344             prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel;
345             prBssInfo->auc2G_20mReqChnlList[0]++;
346         }
347     }
348
349     /* Process intolerant channel report IE */
350     pucIE = (PUINT_8) &prRxFrame->rChnlReport;
351     u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5);
352
353     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
354         switch (IE_ID(pucIE)) {
355         case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT:
356             prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE;
357
358             if (prChnlReport->ucLength <= 1) {
359                 break;
360             }
361
362             /* To do: process regulatory class. Now we assume 2.4G band */
363
364             for (j = 0; j < prChnlReport->ucLength - 1; j++) {
365                 /* Update non-HT channel list */
366                 ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
367                 for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] &&
368                      i <= CHNL_LIST_SZ_2G; i++) {
369                     if (prBssInfo->auc2G_NonHtChnlList[i] ==
370                         prChnlReport->aucChannelList[j]) {
371                         break;
372                     }
373                 }
374                 if ((i > prBssInfo->auc2G_NonHtChnlList[0]) &&
375                     (i <= CHNL_LIST_SZ_2G)) {
376                     prBssInfo->auc2G_NonHtChnlList[i] =
377                                     prChnlReport->aucChannelList[j];
378                     prBssInfo->auc2G_NonHtChnlList[0]++;
379                 }
380             }
381             break;
382
383         default:
384             break;
385         }
386     } /* end of IE_FOR_EACH */
387
388     if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) {
389         bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex);
390         rlmSyncOperationParams(prAdapter, prBssInfo);
391     }
392
393     /* Check if OBSS scan exemption response should be sent */
394     if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ) {
395         rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb);
396     }
397 }
398
399 /*----------------------------------------------------------------------------*/
400 /*!
401 * \brief
402 *
403 * \param[in]
404 *
405 * \return none
406 */
407 /*----------------------------------------------------------------------------*/
408 VOID
409 rlmProcessHtAction (
410     P_ADAPTER_T     prAdapter,
411     P_SW_RFB_T      prSwRfb
412     )
413 {
414     P_ACTION_NOTIFY_CHNL_WIDTH_FRAME    prRxFrame;
415     P_STA_RECORD_T                      prStaRec;
416
417     ASSERT(prAdapter);
418     ASSERT(prSwRfb);
419
420     prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader;
421     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
422
423     if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH ||
424         !prStaRec || prStaRec->ucStaState != STA_STATE_3 ||
425         prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) {
426         return;
427     }
428
429     /* To do: depending regulation class 13 and 14 based on spec
430      * Note: (ucChannelWidth==1) shall restored back to original capability,
431      *       not current setting to 40MHz BW here
432      */
433     if (prRxFrame->ucChannelWidth == 0) {
434         prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH;
435     }
436     else if (prRxFrame->ucChannelWidth == 1) {
437         prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH;
438     }
439     cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
440 }
441
442 /*----------------------------------------------------------------------------*/
443 /*!
444 * \brief
445 *
446 * \param[in]
447 *
448 * \return none
449 */
450 /*----------------------------------------------------------------------------*/
451 VOID
452 rlmHandleObssStatusEventPkt (
453     P_ADAPTER_T                 prAdapter,
454     P_EVENT_AP_OBSS_STATUS_T    prObssStatus
455     )
456 {
457     P_BSS_INFO_T            prBssInfo;
458
459     ASSERT(prAdapter);
460     ASSERT(prObssStatus);
461     ASSERT(prObssStatus->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX);
462
463     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prObssStatus->ucNetTypeIndex];
464     ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT);
465
466     prBssInfo->fgObssErpProtectMode =
467             (BOOLEAN) prObssStatus->ucObssErpProtectMode;
468     prBssInfo->eObssHtProtectMode =
469             (ENUM_HT_PROTECT_MODE_T) prObssStatus->ucObssHtProtectMode;
470     prBssInfo->eObssGfOperationMode =
471             (ENUM_GF_MODE_T) prObssStatus->ucObssGfOperationMode;
472     prBssInfo->fgObssRifsOperationMode =
473             (BOOLEAN) prObssStatus->ucObssRifsOperationMode;
474     prBssInfo->fgObssBeaconForcedTo20M =
475             (BOOLEAN) prObssStatus->ucObssBeaconForcedTo20M;
476
477     /* Check if Beacon content need to be updated */
478     rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE);
479 }
480
481
482 /*----------------------------------------------------------------------------*/
483 /*!
484 * \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX.
485 *
486 * \param[in]
487 *
488 * \return none
489 */
490 /*----------------------------------------------------------------------------*/
491 VOID
492 rlmUpdateParamsForAP (
493     P_ADAPTER_T     prAdapter,
494     P_BSS_INFO_T    prBssInfo,
495     BOOLEAN         fgUpdateBeacon
496     )
497 {
498     P_LINK_T                prStaList;
499     P_STA_RECORD_T          prStaRec;
500     BOOLEAN                 fgErpProtectMode, fgSta40mIntolerant;
501     BOOLEAN                 fgUseShortPreamble, fgUseShortSlotTime;
502     ENUM_HT_PROTECT_MODE_T  eHtProtectMode;
503     ENUM_GF_MODE_T          eGfOperationMode;
504     UINT_8                  ucHtOpInfo1;
505
506     ASSERT(prAdapter);
507     ASSERT(prBssInfo);
508
509     if (!IS_BSS_ACTIVE(prBssInfo) ||
510         prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) {
511         return;
512     }
513
514     fgErpProtectMode = FALSE;
515     eHtProtectMode = HT_PROTECT_MODE_NONE;
516     eGfOperationMode = GF_MODE_NORMAL;
517     fgSta40mIntolerant = FALSE;
518     fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed;
519     fgUseShortSlotTime = TRUE;
520     ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN;
521
522     prStaList = &prBssInfo->rStaRecOfClientList;
523
524     LINK_FOR_EACH_ENTRY(prStaRec, prStaList, rLinkEntry, STA_RECORD_T) {
525         //ASSERT(prStaRec);
526         if(!prStaRec){
527            DBGLOG(P2P, TRACE, ("prStaRec is NULL in rlmUpdateParamsForAP() \n"));
528                 break;
529         }
530         if (prStaRec->fgIsInUse && prStaRec->ucStaState == STA_STATE_3 &&
531             prStaRec->ucNetTypeIndex == prBssInfo->ucNetTypeIndex) {
532             if (!(prStaRec->ucPhyTypeSet &
533                   (PHY_TYPE_SET_802_11GN | PHY_TYPE_SET_802_11A))) {
534                 /* B-only mode, so mode 1 (ERP protection) */
535                 fgErpProtectMode = TRUE;
536             }
537
538             if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
539                 /* BG-only or A-only */
540                 eHtProtectMode = HT_PROTECT_MODE_NON_HT;
541             }
542             else if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) {
543                 /* 20MHz-only */
544                 if (eHtProtectMode == HT_PROTECT_MODE_NONE && 
545                                                 prBssInfo->fgAssoc40mBwAllowed) {
546                     eHtProtectMode = HT_PROTECT_MODE_20M;
547                 }
548             }
549
550             if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF)) {
551                 eGfOperationMode = GF_MODE_PROTECT;
552             }
553
554             if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)) {
555                 fgUseShortPreamble = FALSE;
556             }
557
558             if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) {
559                 fgUseShortSlotTime = FALSE;
560             }
561
562             if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) {
563                 fgSta40mIntolerant = TRUE;
564             }
565         }
566     } /* end of LINK_FOR_EACH_ENTRY */
567
568     /* Check if HT operation IE about 20/40M bandwidth shall be updated */
569     if (prBssInfo->eBssSCO != CHNL_EXT_SCN) {
570         if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant &&
571             !prBssInfo->fgObssActionForcedTo20M &&
572             !prBssInfo->fgObssBeaconForcedTo20M) {
573
574             ucHtOpInfo1 = (UINT_8)
575                 (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH);
576         }
577     }
578
579     /* Check if any new parameter may be updated */
580     if (prBssInfo->fgErpProtectMode != fgErpProtectMode ||
581         prBssInfo->eHtProtectMode != eHtProtectMode ||
582         prBssInfo->eGfOperationMode != eGfOperationMode ||
583         prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 ||
584         prBssInfo->fgUseShortPreamble != fgUseShortPreamble ||
585         prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) {
586
587         prBssInfo->fgErpProtectMode = fgErpProtectMode;
588         prBssInfo->eHtProtectMode = eHtProtectMode;
589         prBssInfo->eGfOperationMode = eGfOperationMode;
590         prBssInfo->ucHtOpInfo1 = ucHtOpInfo1;
591         prBssInfo->fgUseShortPreamble = fgUseShortPreamble;
592         prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime;
593
594         if (fgUseShortSlotTime) {
595             prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;
596         }
597         else {
598             prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME;
599         }
600
601         rlmSyncOperationParams(prAdapter, prBssInfo);
602         fgUpdateBeacon = TRUE;
603     }
604
605     /* Update Beacon content if related IE content is changed */
606     if (fgUpdateBeacon) {
607         bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex);
608     }
609 }
610
611
612 /*----------------------------------------------------------------------------*/
613 /*!
614 * \brief    Initial the channel list from the domain information.
615 *                 This function is called after P2P initial and Domain information changed.
616 *                 Make sure the device is disconnected while changing domain information.
617 *
618 * \param[in] prAdapter  Pointer of ADAPTER_T
619 *
620 * \return boolean value if probe response frame is
621 */
622 /*----------------------------------------------------------------------------*/
623 VOID
624 rlmFuncInitialChannelList (
625     IN P_ADAPTER_T prAdapter
626     )
627 {
628     P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T)NULL;
629     P_DOMAIN_INFO_ENTRY prDomainInfoEntry = (P_DOMAIN_INFO_ENTRY)NULL;
630     P_DOMAIN_SUBBAND_INFO prDomainSubBand = (P_DOMAIN_SUBBAND_INFO)NULL;
631     P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)NULL;
632     UINT_32 u4Idx = 0, u4IdxII = 0;
633     UINT_8 ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE;
634 #if 0
635     UINT_8 ucSocialChnlSupport = 0, ucAutoChnl = 0;
636 #endif
637
638     do {
639         ASSERT_BREAK(prAdapter != NULL);
640
641         prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
642 #if 0
643         ucAutoChnl = prP2pConnSetting->ucOperatingChnl;
644 #endif
645
646         prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter);
647
648         ASSERT_BREAK((prDomainInfoEntry != NULL) && (prP2pConnSetting != NULL));
649
650         prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
651
652         for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) {
653             prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx];
654
655
656             if (((prDomainSubBand->ucBand == BAND_5G) && (!prAdapter->fgEnable5GBand)) ||
657                     (prDomainSubBand->ucBand == BAND_NULL)) {
658                 continue;
659             }
660
661
662             if (ucBufferSize < (P2P_ATTRI_LEN_CHANNEL_ENTRY + prDomainSubBand->ucNumChannels)) {
663                 /* Buffer is not enough to include all supported channels. */
664                 break; // for
665             }
666
667             prChannelEntryField->ucRegulatoryClass = prDomainSubBand->ucRegClass;
668             prChannelEntryField->ucNumberOfChannels = prDomainSubBand->ucNumChannels;
669
670             for (u4IdxII = 0; u4IdxII < prDomainSubBand->ucNumChannels; u4IdxII++) {
671                 prChannelEntryField->aucChannelList[u4IdxII] = prDomainSubBand->ucFirstChannelNum +
672                             (u4IdxII * prDomainSubBand->ucChannelSpan);
673
674 #if 0
675                 switch (prChannelEntryField->aucChannelList[u4IdxII]) {
676                     case 1:
677                         ucSocialChnlSupport = 1;
678                         break;
679                     case 6:
680                         ucSocialChnlSupport = 6;
681                         break;
682                     case 11:
683                         ucSocialChnlSupport = 11;
684                         break;
685                     default:
686                         break;
687                 }
688
689 #endif
690             }
691
692             if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels)) {
693                 ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
694             }
695             else {
696                 break;
697             }
698
699
700             prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryField +
701                                                                                     P2P_ATTRI_LEN_CHANNEL_ENTRY +
702                                                                                     (UINT_32)prChannelEntryField->ucNumberOfChannels);
703
704         }
705
706 #if 0
707         if (prP2pConnSetting->ucListenChnl == 0) {
708             prP2pConnSetting->ucListenChnl = P2P_DEFAULT_LISTEN_CHANNEL;
709
710             if (ucSocialChnlSupport != 0) {
711                 /* 1. User Not Set LISTEN channel.
712                   * 2. Social channel is not empty.
713                   */
714                 prP2pConnSetting->ucListenChnl = ucSocialChnlSupport;
715             }
716         }
717
718 #endif
719
720         // TODO: 20110921 frog -
721         /* If LISTEN channel is not set,
722           * a random supported channel would be set.
723           * If no social channel is supported, DEFAULT channel would be set.
724           */
725
726         prP2pConnSetting->ucRfChannelListSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize;
727
728 #if 0
729         if (prP2pConnSetting->ucOperatingChnl == 0) {  /* User not set OPERATE channel. */
730
731             if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl)) {
732                 break; // while
733             }
734
735             ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
736
737             prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
738
739             while (ucBufferSize != 0) {
740                 if (prChannelEntryField->ucNumberOfChannels != 0) {
741                     ucAutoChnl = prChannelEntryField->aucChannelList[0];
742                     break; // while
743                 }
744
745                 else {
746                     prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryField +
747                                                                                     P2P_ATTRI_LEN_CHANNEL_ENTRY +
748                                                                                     (UINT_32)prChannelEntryField->ucNumberOfChannels);
749
750                     ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
751                 }
752
753             }
754
755
756
757         }
758
759 #endif
760         /* We assume user would not set a channel not in the channel list.
761           * If so, the operating channel still depends on target deivce supporting capability.
762           */
763
764         // TODO: 20110921 frog -
765         /* If the Operating channel is not set, a channel from supported channel list is set automatically.
766           * If there is no supported channel in channel list, a DEFAULT channel is set.
767           */
768
769     } while (FALSE);
770
771 #if 0
772     prP2pConnSetting->ucOperatingChnl = ucAutoChnl;
773 #endif
774     return;
775 } /* rlmFuncInitialChannelList */
776
777 /*----------------------------------------------------------------------------*/
778 /*!
779 * \brief    Find a common channel list from the local channel list info & target channel list info.
780 *
781 * \param[in] prAdapter  Pointer of ADAPTER_T
782 *
783 * \return boolean value if probe response frame is
784 */
785 /*----------------------------------------------------------------------------*/
786 VOID
787 rlmFuncCommonChannelList (
788     IN P_ADAPTER_T prAdapter,
789     IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII,
790     IN UINT_8 ucChannelListSize
791     )
792 {
793     P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T)NULL;
794     P_CHANNEL_ENTRY_FIELD_T prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T)NULL, prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T)NULL;
795     UINT_8 aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE];
796     UINT_8 ucOriChnlSize = 0, ucNewChnlSize = 0;
797
798
799     do {
800
801         ASSERT_BREAK(prAdapter != NULL);
802
803         prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
804
805         prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T)aucCommonChannelList;
806
807         while (ucChannelListSize > 0) {
808
809             prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
810             ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize;
811
812             while (ucOriChnlSize > 0) {
813                 if (prChannelEntryI->ucRegulatoryClass == prChannelEntryII->ucRegulatoryClass) {
814                     prChannelEntryIII->ucRegulatoryClass = prChannelEntryI->ucRegulatoryClass;
815                     // TODO: Currently we assume that the regulatory class the same, the channels are the same.
816                     kalMemCopy(prChannelEntryIII->aucChannelList, prChannelEntryII->aucChannelList, prChannelEntryII->ucNumberOfChannels);
817                     prChannelEntryIII->ucNumberOfChannels = prChannelEntryII->ucNumberOfChannels;
818
819                     ucNewChnlSize += P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryIII->ucNumberOfChannels;
820
821                     prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryIII +
822                                                                                 P2P_ATTRI_LEN_CHANNEL_ENTRY +
823                                                                                 (UINT_32)prChannelEntryIII->ucNumberOfChannels);
824                 }
825
826                 ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels);
827
828                 prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryI +
829                                                                                 P2P_ATTRI_LEN_CHANNEL_ENTRY +
830                                                                                 (UINT_32)prChannelEntryI->ucNumberOfChannels);
831
832
833             }
834
835
836             ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels);
837
838             prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryII +
839                                                                                 P2P_ATTRI_LEN_CHANNEL_ENTRY +
840                                                                                 (UINT_32)prChannelEntryII->ucNumberOfChannels);
841
842
843         }
844
845
846         kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize);
847         prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize;
848
849     } while (FALSE);
850
851     return;
852 } /* rlmFuncCommonChannelList */
853
854
855 /*----------------------------------------------------------------------------*/
856 /*!
857 * \brief
858 *
859 * \param[in]
860 *
861 * \return none
862 */
863 /*----------------------------------------------------------------------------*/
864 UINT_8
865 rlmFuncFindOperatingClass (
866     IN P_ADAPTER_T prAdapter,
867     IN UINT_8 ucChannelNum
868     )
869 {
870     UINT_8 ucRegulatoryClass = 0, ucBufferSize = 0;
871     P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T)NULL;
872     P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)NULL;
873     UINT_32 u4Idx = 0;
874
875     do {
876         ASSERT_BREAK(prAdapter != NULL);
877
878         prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
879         ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
880         prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
881
882         while (ucBufferSize != 0) {
883
884             for (u4Idx = 0; u4Idx < prChannelEntryField->ucNumberOfChannels; u4Idx++) {
885                 if (prChannelEntryField->aucChannelList[u4Idx] == ucChannelNum) {
886                     ucRegulatoryClass = prChannelEntryField->ucRegulatoryClass;
887                     break;
888                 }
889
890             }
891
892
893             if (ucRegulatoryClass != 0) {
894                 break; //while
895             }
896             else {
897                 prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryField +
898                                                                                             P2P_ATTRI_LEN_CHANNEL_ENTRY +
899                                                                                             (UINT_32)prChannelEntryField->ucNumberOfChannels);
900
901                             ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels);
902             }
903
904         }
905
906
907     } while (FALSE);
908
909     return ucRegulatoryClass;
910 } /* rlmFuncFindOperatingClass */
911
912
913 /*----------------------------------------------------------------------------*/
914 /*!
915 * \brief
916 *
917 * \param[in]
918 *
919 * \return none
920 */
921 /*----------------------------------------------------------------------------*/
922 BOOLEAN
923 rlmFuncFindAvailableChannel (
924     IN P_ADAPTER_T prAdapter,
925     IN UINT_8 ucCheckChnl,
926     IN PUINT_8 pucSuggestChannel,
927     IN BOOLEAN fgIsSocialChannel,
928     IN BOOLEAN fgIsDefaultChannel
929     )
930 {
931     BOOLEAN fgIsResultAvailable = FALSE;
932     P_CHANNEL_ENTRY_FIELD_T prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T)NULL;
933     P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T)NULL;
934     UINT_8 ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0;
935
936     do {
937         ASSERT_BREAK(prAdapter != NULL);
938
939         if (fgIsDefaultChannel) {
940             ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL;
941         }
942
943
944         prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings;
945         ucBufferSize = prP2pConnSetting->ucRfChannelListSize;
946         prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T)prP2pConnSetting->aucChannelEntriesField;
947
948         while ((ucBufferSize != 0) && (!fgIsResultAvailable)) {
949
950             for (ucIdx = 0; ucIdx < prChannelEntry->ucNumberOfChannels; ucIdx++) {
951                 if ((!fgIsSocialChannel) ||
952                         (prChannelEntry->aucChannelList[ucIdx] == 1) ||
953                         (prChannelEntry->aucChannelList[ucIdx] == 6) ||
954                         (prChannelEntry->aucChannelList[ucIdx] == 11)) {
955
956                     if (prChannelEntry->aucChannelList[ucIdx] <= 11) {
957                         /* 2.4G. */
958                         ucChannelSelected = prChannelEntry->aucChannelList[ucIdx];
959                     }
960                     else if ((prChannelEntry->aucChannelList[ucIdx] < 52) &&
961                             (prChannelEntry->aucChannelList[ucIdx] > 14)) {
962                         /* 2.4G + 5G. */
963                         ucChannelSelected = prChannelEntry->aucChannelList[ucIdx];
964                     }
965
966                     if (ucChannelSelected == ucCheckChnl) {
967                         fgIsResultAvailable = TRUE;
968                         break;
969                     }
970                 }
971
972             }
973
974
975             ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntry->ucNumberOfChannels);
976
977             prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntry +
978                                                                                                 P2P_ATTRI_LEN_CHANNEL_ENTRY +
979                                                                                                 (UINT_32)prChannelEntry->ucNumberOfChannels);
980
981         }
982
983
984
985         if ((!fgIsResultAvailable) && (pucSuggestChannel != NULL)) {
986             DBGLOG(P2P, TRACE, ("The request channel %d is not available, sugguested channel:%d\n", ucCheckChnl, ucChannelSelected));
987             //  Given a suggested channel.
988             *pucSuggestChannel = ucChannelSelected;
989         }
990
991
992     } while (FALSE);
993
994     return fgIsResultAvailable;
995 }
996
997 /*----------------------------------------------------------------------------*/
998 /*!
999 * \brief
1000 *
1001 * \param[in]
1002 *
1003 * \return none
1004 */
1005 /*----------------------------------------------------------------------------*/
1006 ENUM_CHNL_EXT_T
1007 rlmDecideScoForAP (
1008     P_ADAPTER_T     prAdapter,
1009     P_BSS_INFO_T    prBssInfo
1010     )
1011 {
1012     P_DOMAIN_SUBBAND_INFO   prSubband;
1013     P_DOMAIN_INFO_ENTRY     prDomainInfo;
1014     UINT_8                  ucSecondChannel, i, j;
1015     ENUM_CHNL_EXT_T         eSCO;
1016
1017     eSCO = CHNL_EXT_SCN;
1018
1019     if (prBssInfo->eBand == BAND_2G4) {
1020         if (prBssInfo->ucPrimaryChannel != 14) {
1021             eSCO = (prBssInfo->ucPrimaryChannel > 7) ?
1022                         CHNL_EXT_SCB : CHNL_EXT_SCA;
1023         }
1024     }
1025     else {
1026         prDomainInfo = rlmDomainGetDomainInfo(prAdapter);
1027         ASSERT(prDomainInfo);
1028
1029         for (i = 0; i < MAX_SUBBAND_NUM; i++) {
1030             prSubband = &prDomainInfo->rSubBand[i];
1031             if (prSubband->ucBand == prBssInfo->eBand) {
1032                 for (j = 0; j < prSubband->ucNumChannels; j++) {
1033                     if ((prSubband->ucFirstChannelNum + j*prSubband->ucChannelSpan)
1034                         == prBssInfo->ucPrimaryChannel) {
1035                         eSCO = (j & 1) ? CHNL_EXT_SCB : CHNL_EXT_SCA;
1036                         break;
1037                     }
1038                 }
1039
1040                 if (j < prSubband->ucNumChannels) {
1041                     break; /* Found */
1042                 }
1043             }
1044         }
1045     }
1046
1047     /* Check if it is boundary channel and 40MHz BW is permitted */
1048     if (eSCO != CHNL_EXT_SCN) {
1049         ucSecondChannel = (eSCO == CHNL_EXT_SCA) ?
1050             (prBssInfo->ucPrimaryChannel+ 4) : (prBssInfo->ucPrimaryChannel- 4);
1051
1052         if (!rlmDomainIsLegalChannel(prAdapter, prBssInfo->eBand, ucSecondChannel)){
1053             eSCO = CHNL_EXT_SCN;
1054         }
1055     }
1056
1057     return eSCO;
1058 }
1059